Genie Vala 泛型和可空类型

Genie Vala Generics and Nullable Types

简单问题:在下面的泛型class中,泛型类型和包含类型应该如何定义才能为空?以下将无法编译。

class Pair? of G1, G2: Object

    _first:G1?
    _second:G2?

    construct()

        _first = null
        _second = null

    def insert( first:G1, second:G2 )

        _first = first
        _second = second

    def insert_first( value:G1 )

        _first = value

    def insert_second( value:G2 )

        _second = value

    def second():G2

        return _second

用法:

var pair = new Pair() of string, string
pair = null

由于 Vala 泛型的工作方式,泛型参数始终可以为空。

只要你不打开 --enable-experimental-non-null class 变量也可以为空,所以你的代码简化为:

[indent=4]
class Pair of G1, G2: Object

    _first:G1
    _second:G2

    construct()

        _first = null
        _second = null

    def insert( first:G1, second:G2 )

        _first = first
        _second = second

    def insert_first( value:G1 )

        _first = value

    def insert_second( value:G2 )

        _second = value

    def second():G2

        return _second

init
    var pair = new Pair of string, string
    pair = null

--enable-experimental-non-null打开时,您必须明确变量的类型。我不知道如何在 Genie 中写这个,我试过这个,但编译器不喜欢它:

init
    pair: Pair? of string, string = new Pair of string, string
    pair = null

在 Vala 中没问题:

class Pair<G1,G2>: Object {
    private G1 first;
    private G2 second;

    public Pair () {
        first = null;
        second = null;
    }

    // ...
}

int main () {
    Pair<string, string>? pair = new Pair<string, string> ();
    pair = null;
    return 0;
}

我无法理解以 null 作为类型的类型参数的概念。我不认为这是一个有用的概念。所以你的 class 的定义是:

[indent = 4]
class Pair of G1, G2: Object

    _first:G1?
    _second:G2?

    def insert( first:G1, second:G2 )
        _first = first
        _second = second

    def insert_first( value:G1 )
        _first = value

    def insert_second( value:G2 )
        _second = value

    def second():G2
        return _second

如果您必须 re-assign 具有对象实例的变量为 null 那么它将是:

[indent = 4]
init
    var pair = new Pair of string,string()
    pair = null

但是,Vala 编译器将在超出范围时解引用 pair。所以我不确定您为什么需要分配 null。

在我看来,空值的使用理想情况下仅在与 C 库交互时使用。如果没有正确检查,访问 null 可能会导致崩溃(分段错误)。例如:

init
    a:int? = 1
    a = null
    var b = a + 1

Vala 编译器确实有一个实验性的 non-null 模式,可以对不安全的代码进行一些检查。如果使用 Vala 开关 --enable-experimental-non-null 编译以下内容:

[indent = 4]
init
    var pair = new Pair of string,string()
    pair = null

你会得到错误:

error: Assignment: Cannot convert fromnull' 到 Pair<string,string>'

如果您了解后果,那么您可以告诉编译器这是可以的:

[indent = 4]
init
    pair:Pair? = new Pair of string,string()
    pair = null