Genie Vala Generics и Nullable Types
Простой вопрос: как в следующем универсальном классе как определить универсальный тип и содержащиеся в нем типы, чтобы их можно было обнулять? Следующее не будет компилироваться.
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
2 ответа
Благодаря тому, как работают Vala Generics, универсальные параметры всегда обнуляются.
Пока вы не включите --enable-experimental-non-null
Переменные класса также могут иметь значение 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
В Вале это не проблема
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;
}
Я не могу обернуть голову вокруг концепции параметра типа, который имеет нулевой тип. Я не думаю, что это полезная концепция. Таким образом, определение вашего класса будет:
[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
Если вы должны переназначить переменную, которая имеет экземпляр объекта, на ноль, то это будет:
[indent = 4]
init
var pair = new Pair of string,string()
pair = null
Компилятор Vala, однако, будет разыменовывать pair
когда это выходит за рамки. Так что я не уверен, почему вы должны назначить ноль.
Использование null в идеале будет использоваться только при взаимодействии с библиотекой C, на мой взгляд. Доступ к нулю может привести к сбою (ошибка сегментации), если он не проверен должным образом. Например:
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