Ответ 1
Там действительно нет причин для использования ?
в этом примере, но есть разница.
На статически типизированной цели f(null)
не будет компилироваться, так как базовые типы Int
, Float
и Bool
там не обнуляются. Однако ?
подразумевает обнуляемость, то есть
function f(?i:Int)
на самом деле так же, как
function f(i:Null<Int> = null)
Как вы можете видеть, что ?
имеет два эффекта:
- Добавляется
null
значение по умолчанию, поэтому вы можете опуститьi
во время вызова:f();
- Тип обернут в
Null<T>
. Хотя это не имеет значения для динамических целей, обычно это приводит к снижению производительности во время выполнения для статических целей (опять же: только для аргументовInt
/Float
/Bool
).
Единственная причина, по которой я могу придумать, почему вы хотите, чтобы аргументы с базовыми типами обнулялись, - это включение необязательного пропуска аргументов. При вызове f
в этом примере i
могу быть пропущен, только если он обнуляем:
class Main {
static function main() {
f("Test"); // 0, "Test"
}
static function f(?i:Int = 0, s:String) {
trace(i, s);
}
}
Обратите внимание, что если вы добавите значение по умолчанию к необязательному аргументу, это значение будет использоваться, даже если вы явно передадите null
:
class Main {
static function main() {
f(); // 0
f(null); // 0
}
static function f(?i:Int = 0) {
trace(i);
}
}