Здравствуйте, para, Вы писали:
P>в чём смысл option.None, если можно вернуть null?
"option[T]" описывает необязательное значение. Значение может быть или не быть. null же в дотнете — это значение указателя.
1. null не применим к вэлью-типам. При использовании же option[T] плевать каков тип у T.
2. null является значением по умолчанию для любого указателя. Часто бывает так, что некоторые поля не должны ни в каком случае содержать null (должны всегда содержать данные). Но на практике null таки появляется полях автоматически при инициализации объекта рантаймом. Можно допустить ошибку и в поле будет null хотя это не должно было случиться по логике программы.
Когда метода (свойство) возвращает option[T], то программист четко понимает, что имеет дело с необязательным значением и должен обязательно проверять его наличие. Обойти такие проверки в немерле можно только явно.
В случае же работы с методом который возвращает некую ссылку на объект не ясно нужно ли проверять ее на null. Так что option[T] — это средство фиксации семантики в контракте метода.
Проблемой option[T] является то, что это ссылочный тип, а значит на его создание уходит относительно довольно много времени. Так что в высоко-нагруженных вычислениях он может создать проблему.
P>и P>нужно ли проверять (x == null) в случае option.Some(x)?
По идее применение option[T] должно исключать это. Но это целиком и полностью остается на совести разработчика. Так что в конкретных случаях может быть как угодно.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, hardcase, Вы писали: H>Про паттенр NullObject слышал?
осторожно отношусь к паттернам. в немерле сначала подумал про сопоставление с образцом
этот паттерн подразумевает конкретное дефолтное поведение, которое в данном случае с водится к H>
H>def y = x.WithDefault(10); // y == 10
H>
и аналогичным методам.
но этого же можно добиться по-моему экстеншн-методом. сейчас проверить к сожалению не могу
public static WithDefault (this o : T, val : T) : T
where T : class
{
if(o == null)
val
else
o
}
Здравствуйте, VladD2, Вы писали: VD>2. null является значением по умолчанию для любого указателя. Часто бывает так, что некоторые поля не должны ни в каком случае содержать null (должны всегда содержать данные).
данные, которые сводятся к переменной типа None вместо null? и что с ней делать кроме проверки?
VD>В случае же работы с методом который возвращает некую ссылку на объект не ясно нужно ли проверять ее на null. Так что option[T] — это средство фиксации семантики в контракте метода.
очень хорошая возможность, но при этом было бы логично запретить использование, передачу в качестве параметра и возврат из метода значения null, причём на уровне рантайма (утопия ) и тем более для Some.
пока что я вижу option только как средство синтаксической унификации структур и классов.
довольно часто встречаю использование этой конструкции, но её использование обычно не
def y = x.WithDefault(10); // y == 10
а
match (x) {
| Some => ...
| _ => ...
что было бы эквивалентно проверке на null, только больше писанины.
Зы. я не докапываюсь, а искренне хочу понять суть.
Здравствуйте, para, Вы писали:
P>Про структурные типы вопросов нет.
P>Здравствуйте, hardcase, Вы писали: H>>Про паттенр NullObject слышал? P>осторожно отношусь к паттернам. в немерле сначала подумал про сопоставление с образцом
P>этот паттерн подразумевает конкретное дефолтное поведение, которое в данном случае с водится к H>>
H>>def y = x.WithDefault(10); // y == 10
H>>
P>и аналогичным методам. P>но этого же можно добиться по-моему экстеншн-методом. сейчас проверить к сожалению не могу
Как ты сведешь к экстеншонам GetHashCode и Equals?
Огромная просьба не отвечать на сообщения скопом. Это не ленточный сервис, древесный. Ты нарушаешь иерархию сообщений и препятствуешь работе системе оповещения об ответах. Я мог вообще не узнать что мне ответили.
P>данные, которые сводятся к переменной типа None вместо null? и что с ней делать кроме проверки?
Оно и нужно исключительно для проверок. Точнее для того чтобы их не забыли сделать.
P>очень хорошая возможность, но при этом было бы логично запретить использование, передачу в качестве параметра и возврат из метода значения null, причём на уровне рантайма (утопия ) и тем более для Some.
Ну, рантайм не переделать. Но и без этого option очень положительно влияет на качество кода и резко уменьшает количество ошибок связанных с не обработкой отсутствия значения.
P>пока что я вижу option только как средство синтаксической унификации структур и классов.
Что-то очень умно завернуто.
P>довольно часто встречаю использование этой конструкции, но её использование обычно не P>
P>def y = x.WithDefault(10); // y == 10
P>
P>а P>
P> match (x) {
P> | Some => ...
P> | _ => ...
P>
P>что было бы эквивалентно проверке на null, только больше писанины.
А ты подумал, какой у 10 может быть null?
P>Зы. я не докапываюсь, а искренне хочу понять суть.
option на практике делает действия с необязательными данными намного более понятными. Видя проверку:
match (x)
{
| Some(y) => y...
| _ => ...
}
ты отчетливо понимаешь, что здесь проверяется отсутствие или наличие значения, а не просто проверка на null c целью чтобы не долбонуло.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, para, Вы писали:
P>Здравствуйте, catbert, Вы писали:
P>>>нужно ли проверять (x == null) в случае option.Some(x)?
C>>Если внутри option-а ссылочный тип, да, к сожалению.
P>мне кажется стоит добавить в конструктор Some соответствующий асерт.
Какую проблему ты пытаешься этим решить?
Ассерт добавить такой система типов .NET не позволит тебе.
Здравствуйте, para, Вы писали:
P>да можно и целый макрос уровня сборки сделать, который бы вставлял асерты по дефолту во все методы. только как быть с внешними библиотеками?
Вот именно:
def result = Some(LibraryFunctionFromAnotherAssembly()); // неприятно будет
С другой стороны, можно добавить в язык какую-нибудь фичу, которая перед запаковкой в option требовала бы матча с null-ом. Только я не думаю, что эта фича оправдает затраты на свою реализацию.
Вообще-то, можно прямо сейчас добавть функцию (если ее уже нету) в вариант Option, которая бы проверяла ReferenceEquals(x, null) и возвращала соответственно либо None либо Some с не-null'ом. Но такое решение вообще-то не решение, потому что никто не мешает создать option по-другому.
А вот объявить конструкторы option закрытыми, и оставить только один способ создания — вроде хорошая идея. Точнее, это идея, в которой я не могу найти проблем.
Здравствуйте, VladD2, Вы писали:
VD>Проблемой option[T] является то, что это ссылочный тип, а значит на его создание уходит относительно довольно много времени. Так что в высоко-нагруженных вычислениях он может создать проблему.
А почему не сделать бы option структурой с двумя полями?
Help will always be given at Hogwarts to those who ask for it.
Здравствуйте, VladD2, Вы писали:
VD>Проблемой option[T] является то, что это ссылочный тип, а значит на его создание уходит относительно довольно много времени. Так что в высоко-нагруженных вычислениях он может создать проблему.
Кстати, у конкурентов в f# значение None заменяется в байт-коде на обычный null. На днях словил из-за этого NullReferenceException. Просто попытался в отладочном коде вызвать ToString() для значения Option, а не тут-то было.
Здравствуйте, dsorokin, Вы писали:
D>Кстати, у конкурентов в f# значение None заменяется в байт-коде на обычный null. На днях словил из-за этого NullReferenceException. Просто попытался в отладочном коде вызвать ToString() для значения Option, а не тут-то было.
Вот потому — это и не есть хорошее решение. Хорошего решение же для дотнета сделать будет не просто, так как сам дотнет трактует null как значение по умолчанию для всех ссылочных данных, а ведь кроме классов есть еще структуры которые могут инициализироваться автоматически.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
VD>option на практике делает действия с необязательными данными намного более понятными.
Кроме того, он делает и описания типов более понятными:
class Foocator
{
public Id : int { get; private set; }
public MyBar : BarInfo { get; private set; } // может ли MyBar быть null?
}
/** или **/class Foocator
{
public Id : int { get; private set; }
public MyBar : option[BarInfo] { get; private set; } // явно указано, что MyBar опционален
}
Нуллабл-типы определены только для структур, так что их так использовать не выйдет.
Здравствуйте, hardcase, Вы писали:
_FR>>А почему не сделать бы option структурой с двумя полями?
H>Такая мысль есть, недавно Влад закоммитил в стандартную библиотеку структуру ValueOption. Есть определенные мысли научить ПМ работать с ней.