Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >nim的引用和指针

nim的引用和指针

作者头像
liulun
发布于 2018-01-12 07:31:16
发布于 2018-01-12 07:31:16
95000
代码可运行
举报
文章被收录于专栏:liulunliulun
运行总次数:0
代码可运行

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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.}配置节

请看如下示例代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
{.experimental.}
proc depth(x: NodeObj): int = ...
var
  n: Node
new(n)
echo n.depth

也不用写成n[].depth

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

下面的写法是错误的

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
type MyTuple = tuple[a: ref MyTuple]

同样 T = ref T 也是错误的

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

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
type
  Node = ref object
    le, ri: Node
    data: int

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

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

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

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

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

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

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

请看下面的示例代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2015-08-28 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
C++ 选择 引用传递还是指针传递
在C++编程中,选择引用传递(pass-by-reference)还是指针传递(pass-by-pointer)取决于具体的需求和上下文。下面是一些关于它们各自特点和适用场景的分析:
jasong
2025/03/26
802
STL list源码分析以及实现
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/haluoluo211/article/details/80643481
bear_fish
2018/09/14
1.6K0
STL list源码分析以及实现
Nim教程【十一】
引用类型和指针类型 不同的引用可以只想和修改相同的内存单元 在nim中有两种引用方式,一种是追踪引用,另一种是非追踪引用 非追踪引用也就是指针,指向手动在内存中分配的对象; 追踪引用指向一个垃圾收集的对象; 非追踪引用是不安全的 然而对于一些低级操作(比如说访问硬件),非追踪引用是不可避免的 追踪引用用ref关键词声明 非追踪引用用ptr关键词声明 可以用[]来解包一个引用(访问一个元组或对象域时要用到) 请看下面的代码: type   Node = ref NodeObj   NodeObj = obje
liulun
2018/01/12
8060
Nim教程【十四】
网友@沉没捕鱼,赞助了一台服务器 这个系列的教程写完之后,我们就要开始着手搭建Nim的社区了~ 异常 Nim中的异常类型是对象类型 根据惯例,Nim中的异常类型的命名都应该以Error后缀结尾 在system模块中定义了异常类型的基类 所有的异常都应该派生自system.Exception类型 由于我们不清楚异常对象的生命周期, 所以必须在内存堆上为异常的实例分配空间 编译器不允许开发人员在栈上为异常分配空间 你如果想抛出一个异常,你必须为这个异常的msg属性赋值 按照约定,只有在非常特殊的情况下才应该引发
liulun
2018/01/12
8410
Nim教程【十二】
排除指定符号 一般情况下使用import语句,会把一个模块内的符号都导入进来 如果你像排除特定的符号(不想让某些符号被导入进来) 可以使用except子句 就像下面这样 import mymodule except y 这行代码排除了mymodule模块中的y符号,其他符号都导入了 如果想排除更多的符号,可以使用逗号分割 导入指定符号 我们还可以使用from语句来导入指定的符号 请看下面的代码: from mymodule import x, y, z 上面的代码中,只导入了mymodule模块的x,y,z
liulun
2018/01/12
6080
深入理解 C++11 智能指针:独占、共享与弱引用的完美管理
unique_ptr是最常用的一种智能指针,它确保一个指针在同一时刻只能有一个所有者。当unique_ptr超出作用域时,它所持有的资源会自动被销毁。
用户11286421
2025/03/24
2780
深入理解 C++11 智能指针:独占、共享与弱引用的完美管理
《逆袭进大厂》第二弹之C++进阶篇59问59答(超硬核干货)
先扯两句闲话,前段时间加了一个粉丝,他告诉我说他们老师在班级群里推荐了我,我当时听到都懵了。。。
拓跋阿秀
2021/03/22
2.4K0
《逆袭进大厂》第二弹之C++进阶篇59问59答(超硬核干货)
C++ const各种用法总结
原文链接:https://www.toutiao.com/i6644404128439075332/
Steve Wang
2019/09/23
2K0
nim语言木马开发初探
在经过一段时间研究使用go语言进行shellcode加载器免杀之后发现go语言的效果并没有以前那么好了,在近一段时间看公众号文章时发现了nim语言,该语言很小众,杀软对其针对的力度可能比较小,在教育护网前做一个初步的研究。
yulate
2023/05/02
7880
nim语言木马开发初探
[Rust笔记] 我也谈 Box<T>智能指针·实践领悟
不夸张地讲,Box<T>就是【堆·数据】在【栈】内存中的“全权·代理人”。具有同类特点的【智能指针】还包括String和CString等。
MikeLoveRust
2022/11/28
6950
整理了70道C语言与C++常见问答题
变量的定义为变量分配地址和存储空间, 变量的声明不分配地址。一个变量可以在多个地方声明, 但是只在一个地方定义。 加入extern 修饰的是变量的声明,说明此变量将在文件以外或在文件后面部分定义。
C语言与CPP编程
2021/02/07
3.2K0
整理了70道C语言与C++常见问答题
【C++终极篇】C++11:编程新纪元的神秘力量揭秘
但是到了c++11实现了可以用{}对容器进行一些初始化等,比如push/inset多参数构造的对象时,{}初始化会很⽅便,这是因为每个类型它都会有个initializer_list的一个构造,这样就方便了我们操作。
羑悻的小杀马特.
2025/01/23
350
【C++终极篇】C++11:编程新纪元的神秘力量揭秘
Nim编码风格
介绍 Nim语言不限制开发人员使用哪种具体的编码风格, 但为了社区的发展,在编写一些标准库的时候还是应该遵从统一的编码风格 这篇文章会列出一系列的编码风格准则,供大家参考。 但值得注意的是,有很多例外场景会与这些准则相悖, 而且,nim语言非常灵活,在一些特定上下文中,这些编码风格准则也不适用。 跟python相似,python的编码风格在不断演化、改变, nim语言也是这样,随着时间的推移,这个编码风格准则也会改变。 在编写nim的基础类库、编译器、官方工具的时候, 强制要求遵从这些编码风格准则 间距和空
liulun
2018/01/12
1K0
《编程千问》第九问:能否尽可能详细阐述指针和引用的区别?
在C++中,**指针(Pointer)和引用(Reference)**是两个非常重要的概念,分别提供了不同方式来操作内存地址和数据。以下内容从概念、特点、底层原理和实现等多个角度详尽阐述。
码事漫谈
2024/12/20
660
《编程千问》第九问:能否尽可能详细阐述指针和引用的区别?
浅析C++中的RTTI:运行时类型识别
在 C++ 编程中,我们经常需要处理各种复杂的对象类型和继承层次结构。在某些情况下,我们需要在运行时了解对象的真实类型,并根据其类型执行相应的操作。这正是 RTTI(Run-Time Type Identification)的用武之地。
程序员的园
2024/07/18
1250
浅析C++中的RTTI:运行时类型识别
【c++】智能指针详解&&c++特殊类设计&&c++的类型转换
下面我们先分析一下下面这段程序有没有什么内存方面的问题?提示一下:注意分析MergeSort函数中的问题
用户10925563
2024/08/06
2040
【c++】智能指针详解&&c++特殊类设计&&c++的类型转换
【重学C++】02 脱离指针陷阱:深入浅出 C++ 智能指针
在上一讲《01 C++如何进行内存资源管理》中,提到了对于堆上的内存资源,需要我们手动分配和释放。管理这些资源是个技术活,一不小心,就会导致内存泄漏。
会玩code
2023/07/08
4460
【重学C++】02 脱离指针陷阱:深入浅出 C++ 智能指针
STL容器的线程安全性了解多少?
STL的意思是与迭代器合作的C++标准库的一部分,包括标准容器(包括string),iostream库的一部分,函数对象和算法,它不包括标准容器适配器(stack,queue和priority_queue)以及bitset和valarray容器,因为它们缺乏迭代器的支持,也不包括数组。数组以指针的形式支持迭代器,但数组是C++语言的一部分,并非库。
用户9831583
2022/12/04
1.5K0
C++中指针和引用的区别
指针和引用主要有以下区别: 引用必须被初始化,但是不分配存储空间。指针不声明时初始化,在初始化的时候需要分配存储空间。 引用初始化后不能被改变,指针可以改变所指的对象。 不存在指向空值的引用,但是存在指向空值的指针。 注意:引用作为函数参数时,会引发一定的问题,因为让引用作参数,目的就是想改变这个引用所指向地址的内容,而函数调用时传入的是实参,看不出函数的参数是正常变量,还是引用,因此可能引发错误。所以使用时一定要小心谨慎。 从概念上讲。指针从本质上讲就是存放变量地址的一个变量,在逻辑上是独立的,它可以被改
猿人谷
2018/01/17
5.1K0
指针的艺术——指针与引用的区别
C++的指针和引用是两个重要的概念,它们都用于间接访问对象。引用变量是另一个变量的另一个名称,可以通过引用变量直接访问到该变量。同样指针变量也可以这样使用。
鳄鱼儿
2024/11/03
1050
相关推荐
C++ 选择 引用传递还是指针传递
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验