为Julia中的对象设置终结器函数

为Julia中的对象设置终结器函数,julia,Julia,我正在调试一些Julia代码,并试图找出以下代码不起作用的原因。(朱莉娅0.6.3) 虽然我希望它打印“finalized!”,但实际上我得到了以下错误: ERROR: objects of type Foo cannot be finalized Stacktrace: [1] finalizer(::Any, ::Any) at ./base.jl:127 我几乎找不到关于finalizer函数的文档,也没有示例,我做错了什么?如果您查找finalizer帮助,您将了解对象的类型必须是可

我正在调试一些Julia代码,并试图找出以下代码不起作用的原因。(朱莉娅0.6.3)

虽然我希望它打印“finalized!”,但实际上我得到了以下错误:

ERROR: objects of type Foo cannot be finalized
Stacktrace:
 [1] finalizer(::Any, ::Any) at ./base.jl:127

我几乎找不到关于finalizer函数的文档,也没有示例,我做错了什么?

如果您查找
finalizer
帮助,您将了解对象的类型必须是可变结构

特别是在base.jl文件中的
finalizer
定义中,您可以看到有一个检查:

if isimmutable(o)
    error("objects of type ", typeof(o), " cannot be finalized")
end
这意味着您不能为不可变对象设置终结器

在Julia 0.7中,
finalizer
的语法有点不同,但行为相同,请参阅

下面是一个可变结构的示例:

julia> mutable struct Foo
           foo::String
       end

julia> k = Foo("bar")
Foo("bar")

julia> finalizer(k, k->print("finalized!"))

julia> finalize(k)
finalized!

有人知道这里要求可变的原因吗?与本例一样,可能存在一个不可变字符串,表示需要finalizerAFAIK垃圾收集器触发器终结器的资源,不可变对象不会被垃圾收集。实际上,
String
是一个特例。它在语言中是不可变的,但实际上它在内部被
isimmutable
函数或
String.mutable
字段视为可变的。因此,您可以将终结器附加到
字符串
(但不能附加到围绕
字符串
)的不可变对象。我有点明白,但我假设“isbits()”类型不是GC'd(因为它们可能是堆栈分配的),而不是不可变的。现在,
isbits
的问题正是我们在问题中遇到的情况,
Foo(“a”)
不是bits类型,isbits:=isimmutable+不包含引用(因此它是一个比不变性更强的属性)。以文件句柄为例,它可以是“isbits”类型(它是一个整数),虽然应该最终确定(“文件关闭”),但我想我正在寻找一些RAII机制(而不是在“do块”上下文中)
julia> mutable struct Foo
           foo::String
       end

julia> k = Foo("bar")
Foo("bar")

julia> finalizer(k, k->print("finalized!"))

julia> finalize(k)
finalized!