gre*_*man 21 types pointers nim-lang
注意:我不是在询问指针和引用之间的区别,对于这个问题,它完全无关紧要.
有一点我无法明确说明 - 尼姆罗德使用的是什么型号?
就像C++一样 - 你有值并且new你创建了指向数据的指针(在这种情况下,变量可以保存指向指向数据的指针的指针)?
或者像C# - 你有POD类型作为值,但用户定义的对象有引用(隐式)?
我发现只有dereferencing是自动的,就像在Go中一样.
另一种方式.你定义你的新类型,比方说Student(名字,大学,地址).你写:
var student ...?
Run Code Online (Sandbox Code Playgroud)
student保持实际数据(的Student类型/类)student持有的指针数据student持有指针的指针数据或者那些点不可能?
Grz*_*icz 28
默认情况下,模型是按值传递数据.当您创建特定类型的var时,编译器将在堆栈上为变量分配所需的空间.这是预期的,因为Nim编译为C,复杂类型只是结构.但是就像在C或C++中一样,你也可以有指针.还有就是ptr得到一个不安全的指针,大多用于连接C代码关键字,并有一个ref以得到垃圾收集安全引用(在两个记录参考文献和指针类型稔手册的部分).
但是,请注意,即使指定a proc按值传递变量,编译器也可以自由决定在内部通过引用传递它,如果它认为它可以加快执行速度并且同时是安全的.在实践中,我唯一使用引用的时候是我将 Nim类型导出到C并且必须确保C和Nim都指向相同的内存.请记住,您始终可以检查nimcache目录中生成的C代码.然后,您将看到varproc 中的参数只是指向其C结构的指针.
下面是一个类型的示例,其中构造函数将在堆栈上创建并通过值传入,并且相应的指针类似于version:
type
Person = object
age: int
name: string
proc initPerson(age: int, name: string): Person =
result.age = age
result.name = name
proc newPerson(age: int, name: string): ref Person =
new(result)
result.age = age
result.name = name
when isMainModule:
var
a = initPerson(3, "foo")
b = newPerson(4, "bar")
echo a.name & " " & $a.age
echo b.name & " " & $b.age
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,代码基本相同,但存在一些差异:
ref版本允许您返回一个nil值,您可以将其视为错误,而值构造函数会强制您引发异常或更改构造函数以使用下面提到的var形式,以便您可以返回bool表示成功.失败倾向于以不同的方式对待.在类C语言中,theres是一种显式语法,用于访问指针的内存值或其指向的内存值(解除引用).在Nim中也有,它是空的下标符号([]).但是,编译器将尝试自动放置这些以避免混乱代码.因此,该示例不使用它们.要证明这一点,您可以将代码更改为:
echo b[].name & " " & $b[].age
哪个将按预期工作和编译.但是,以下更改将产生编译器错误,因为您无法取消引用非引用类型:
echo a[].name & " " & $a[].age
Nim社区目前的趋势是摆脱单字母前缀来区分价值与参考类型.在旧约定中,您将获得TPerson参考值的a 和别名as PPerson = ref TPerson.您仍然可以使用此约定找到许多代码.
initPerson返回值,你也可以有一个init(x: var Person, ...).但隐式result变量的使用允许编译器对此进行优化,因此更多的是品味偏好或bool将调用传递给调用者的要求.它可以是.
type Student = object ...
Run Code Online (Sandbox Code Playgroud)
大致相当于
typedef struct { ... } Student;
Run Code Online (Sandbox Code Playgroud)
在C,同时
type Student = ref object ...
Run Code Online (Sandbox Code Playgroud)
要么
type Student = ptr object ...
Run Code Online (Sandbox Code Playgroud)
大致相当于
typedef struct { ... } *Student;
Run Code Online (Sandbox Code Playgroud)
在C中(ref表示由垃圾收集器跟踪的引用,ptr而不跟踪).