• nim的引用和指针


    nim语言的引用和其他语言的指针有点相似

    可以提供一种“多对一”的关系

    这就意味着不同的引用可以指向同一个内存位置

    nim区分可被追踪的引用和不可被追踪的引用

    不可被追踪的引用又称为指针

    可被追踪的引用可以被垃圾回收器回收

    不可被追踪的引用指向手动分配的对象,或其他地方创建出来的一块内存区域

    这也就是说,不可被追踪的引用是不安全的

    对于某些底层操作,不可被追踪的引用有其存在的必要

    可被追踪的引用使用ref关键字定义,

    不可被追踪的引用使用ptr关键字定义

    空下标的方括号[]可以用来解引用

    addr方法可以返回一个实例的地址

    对于一个地址来说,它始终是一个不可追踪的引用

    所以addr方法也是一个不安全的方法。

    .操作符和[]操作符可以隐式执行,先来看一下下面的代码

    type
      Node = ref NodeObj
      NodeObj = object
        le, ri: Node
        data: int
    
    var
      n: Node
    new(n)
    n.data = 9

    在上面的代码中,不需要写成n[].data,

    因为方括号操作符已经隐式执行了

    事实上nim官方也强烈不建议写成n[].data

     

    另外,自动解引用操作也直接作用于一个方法的调用

    但目前看来,还必须加上{.experimental.}配置节

    请看如下示例代码:

    {.experimental.}
    proc depth(x: NodeObj): int = ...
    var
      n: Node
    new(n)
    echo n.depth

    也不用写成n[].depth

    为了简化类型检查,nim语言不支持递归元组

    下面的写法是错误的

    type MyTuple = tuple[a: ref MyTuple]

    同样 T = ref T 也是错误的

    如果一个对象只能出现其引用类型,不能出现其值类型

    那么可以用如下方法完成:

    type
      Node = ref object
        le, ri: Node
        data: int

    可以使用内置的new方法为一个可被追踪的对象分配内存

    可以使用alloc、dealloc和realloc来应对不可被追踪的对象

    这些方法的具体信息都可以在system类库的说明文档中找到

    如果一个引用指向为空,那么这个引用的值就是nil

    如果你碰到一个不可被追踪的对象里面包含一个可被追踪的对象(或者是一个字符串、又或者是一个sequences)

    那么就需要特别留意了,为了让一切都正常释放,

    你必须在释放不可被追踪的对象之前,使用内置的GCunref方法处理一下这个对象的那些特殊属性

    请看下面的示例代码:

    type
      Data = tuple[x, y: int, s: string]
    # 在内存堆上创建一个不可被追踪的对象:
    var d = cast[ptr Data](alloc0(sizeof(Data)))
    # create a new string on the garbage collected heap:
    d.s = "abc"
    # 告诉 GC 这个string类型的属性已经没有存在的必要了:
    GCunref(d.s)
    # 释放不可被追踪的对象:
    dealloc(d)

    如果不用GCunref方法处理一下对象的字符串属性,

    那么这个字符串所占用的内存将永远不会被释放

    上面的代码同时也展示了:

    怎么获得一个类型的size

    alloc0方法创建一个没有类型的指针

    cast方法可以绕过类型系统,让指针具有类型ptr Data

    只有在非常必要的时候再用cast方法,因为他会破坏类型安全,导致不可预知的BUG

  • 相关阅读:
    AlwaysOn配置时在连接步骤时报错(35250)
    MongoDB 在系统数据库local上无法创建用户的解决方法
    Elasticsearch 安装操作手册
    SQL Server 数据库调整表中列的顺序操作
    SQL Server 数据库部分常用语句小结(二)
    一个磁盘I/O故障导致的AlwaysOn FailOver 过程梳理和分析
    他人言,以为是,铭记于此。
    MongoDB 基本操作和聚合操作
    MySQL MHA FailOver后,原Master节点自动以Slave角色加入集群的研究与实现
    SQL Sever AlwaysOn的数据同步原理
  • 原文地址:https://www.cnblogs.com/liulun/p/4766250.html
Copyright © 2020-2023  润新知