1

简单的问题:在下面的泛型类中,应该如何定义泛型类型和包含类型以使它们可以为空?以下不会编译。

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
4

2 回答 2

2

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

只要您不打开--enable-experimental-non-null类变量也可以为空,因此您的代码简化为:

[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;
}
于 2018-02-28T09:51:09.347 回答
2

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

[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

如果您必须将具有对象实例的变量重新分配为 null,那么它将是:

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

然而,Vala 编译器会pair在超出范围时取消引用。所以我不确定你为什么需要分配null。

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

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

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

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

你会得到错误:

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

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

[indent = 4]
init
    pair:Pair? = new Pair of string,string()
    pair = null
于 2018-02-28T10:25:17.767 回答