gpt4 book ai didi

nim-lang - 如何获得对 Nim 中现有对象的安全引用?

转载 作者:行者123 更新时间:2023-12-03 21:10:18 24 4
gpt4 key购买 nike

我写了一个 Nim将两个对象作为 var 的过程参数。它们都是一个带有 int 的对象领域level .在做程序的实际工作之前,我想把参数按level较大的顺序排列。 ,所以我这样做:

proc subroutine(param1: var MyObject, param2: var MyObject) =
var large: ptr MyObject = param1.addr
var small: ptr MyObject = param2.addr

# If in wrong order by level, swap large and small
if large.level < small.level:
large = param2.addr
small = param1.addr

# The rest of the proc references, only variables large and small, e.g.,
large.level += 1
small.level += 2
这似乎适用于我的应用程序,但我注意到在 Nim documentation 中, ptr类型称为“不安全”,建议仅用于低级操作。有一个“安全”的引用类型 ref , 建议使用 ref除非你真的想做手动内存管理。
我不想进行手动内存管理,我希望 Nim 垃圾收集器为我处理这些参数的内存,但我没有找到安全的方法 ref的两个参数。
我真的希望能够根据变量 large 编写算法(比我展示的简单代码复杂得多)和 small , 而不是 param1param2 .否则,如果我只能引用参数 param1param2 ,如果不为它们创建这些别名,我必须将相同的算法复制并粘贴两次以分别处理案例 param1.level < param2.levelparam1.level >= param2.level .
有没有更惯用的 Nim 方法来做这样的事情,而不使用 ptr类型?

最佳答案

除非执行对象的副本,否则您无法将安全的对象变为不安全的对象,反之亦然。
普通变量存储在堆栈中,因此当它们的函数作用域存在时将被销毁,但可以将引用存储到全局变量中并在以后访问。如果这是可能的,为了使其安全,编译器/语言需要知道某种从堆栈中提取变量的方法,以便在其作用域存在后仍然有效,或者在背后手动执行复制,或者其他一些神奇的方法事物。
这也是取变量地址不安全的原因。您不能保证它的生命周期,因为您可以将该地址存储在其他地方并稍后尝试使用它。但是,就内存保证而言,这些变量至少应在您的 proc 调用期间保持事件状态,因此在该 proc 中使用这些地址别名应该是安全的,而不必担心。
也就是说,您可以重写代码以使用执行检查的中间代理过程,从而在每个插槽中传递正确的变量。中间过程保证其中一个变量总是很大,你可以避免使用不安全的引用:

type
MyObject = object
level: int

proc subroutine_internal(large: var MyObject, small: var MyObject) =
assert large.level >= small.level
large.level += 1
small.level += 2

proc subroutine(param1: var MyObject, param2: var MyObject) =
if param1.level < param2.level:
subroutine_internal(param2, param1)
else:
subroutine_internal(param1, param2)

proc main() =
var
a = MyObject(level: 3)
b = MyObject(level: 40)

subroutine(a, b)
echo a, b

main()

关于nim-lang - 如何获得对 Nim 中现有对象的安全引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64254492/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com