为什么这个函数 return 一个(拥有的)值?

Why this function return an (owned) value?

代码 来自:

def repeatwithsep (e: string, n: int, separator: string): string
    var elen = e.length;
    var slen = separator.length;
    var a = new StringBuilder.sized ((elen * n) + (slen * (n - 1)) + 1);
    for var i = 0 to (n - 1)
        if i != 0
            a.append_len (separator, slen)
        a.append_len (e, elen)
    return (owned) a.str

var a是一个局部变量,当a超出范围时,它就会被销毁。 为什么这个功能

return(拥有)a.str

有什么区别

return a.str

return(拥有)a.str

(拥有)有什么好处

return a.str 将使用 g_strdup 复制字符串,因为默认情况下,函数结果和 StringBuilder 在(隐式)赋值后都将拥有一个单独的字符串副本。

由于存储在 a 中的 StringBuilder 将超出范围,因此它的副本将永远不会被再次使用,这在这种情况下是不可取的/高效的。

因此解决方案是使用 (owned) 指令将字符串的所有权从 a.str 传递给函数的结果。

顺便说一句:您可以通过使用 valac -C 编译两个版本并比较生成的 C 代码来轻松找到这一点:

-       _tmp21_->str = NULL;
-       result = _tmp22_;
+       _tmp23_ = g_strdup (_tmp22_);
+       result = _tmp23_;

(在此比较中,左侧为 return (owned) a.str,右侧为 return a.str

PS:这在 ownership section of the Vala tutorial and also the corresponding part of the Genie tutorial.

中有记录

我也推荐Reference Handling article