转让所有权(Genie / Vala)

时间:2015-10-28 10:01:30

标签: compiler-errors vala genie

有一个简单的例子:

country:value

如果编译此代码,则会出现错误:"具有强引用的局部变量用作返回值,方法返回类型尚未声明为转移所有权"。如何更改编译成功发生的代码?

3 个答案:

答案 0 :(得分:2)

是什么让你认为回报价值应该是无主的?

如果是因为没有unowned Vala编译器提供了"error: 'MyStruct' is not a supported generic type argument, use '?' to box value types",那么您可以尝试使用list of MyStruct?。这个"框" [1] [2]基本的C数据类型,因此它可以在底层的GObject类型系统中使用。

如果是因为您阅读了教程以及"弱引用","无主参考文献","所有权转移"和"指针"那么我认为您应该将这些主题视为高级主题。我认为他们应该在某个时候被移动到一个单独的页面,供那些想深入了解Genie的人们使用。

Vala编译器,以及Genie,已经协助了内存管理。这意味着在后台为您提供一切照顾。 Vala编译器具有合理的默认行为,因此您不需要更改内容。

作为Genie程序员,您应该了解与C库接口的可空类型,并且引用计数可能会在创建循环引用时产生内存泄漏[3]。除此之外,请查看Genie教程该部分中的主题,以及真正想深入了解Genie如何工作和解决问题的人。

结构可以被认为是物体的先驱。结构是复合数据类型。 Vala / Genie中结构的内存由堆栈上的C编译器处理[4]。这可能会给他们带来性能优势。但是,通常情况下,最好为复合数据类型使用一个类,因为它们更适合底层的GObject类型系统。但是,如果您尝试大量优化某些代码以获得速度[5]或与使用结构的C库接口,则可能需要使用结构。

所以简短的回答是与Jens'使用类的解决方案,除非你有充分的理由不这样做。

[1] - https://developer.gnome.org/gobject/stable/gobject-Boxed-Types.html

[2] - Vala interface generics compiler error

[3] - https://wiki.gnome.org/Projects/Vala/ReferenceHandling

[4] - https://wiki.gnome.org/Projects/Vala/Tutorial#Structs

[5] - http://zee-nix.blogspot.co.uk/2008/09/think-before-you-create-gobjects.html

答案 1 :(得分:1)

在任何给定时间必须至少有一个对象的引用。在这里,您创建一个变量result,它具有对列表的引用。当你退回时,你坚持认为它是unowned list of MyStruct。这意味着返回没有引用,result超出范围,因此列表现在没有对它的引用,将被取消分配。

您实际上正在返回一个悬空参考。返回list of MyStruct,以便调用者具有引用或将副本置于某个共享状态(全局变量或字段)。

答案 2 :(得分:0)

精灵列表实际上是“伪装”中的Gee.List<T>,它是一种类型,所以它将被引用计数。

类型推断的var变量目前始终是一个拥有的变量(在Vala bug跟踪器中有关于此的错误报告)。

所以result是对类实例的强引用。你无法将其作为无主参考返回。

我强烈建议您使用类而不是MyStruct的结构。

否则您将遇到内存管理问题(结构不计入引用)。

您不必担心复制和所有权:

class MyStruct
    a: int
    b: int

def my_proc(): list of MyStruct
    var result = new list of MyStruct
    for var i = 1 to 10
        var my_struct = new MyStruct()
        my_struct.a = i
        my_struct.b = i*i
        result.add(my_struct)
    return result

init
    pass

编辑:如果您希望列表包含多个值,您还必须在循环内部分配my_struct!我已更新我的代码以反映这一点。