Здравствуйте, D. Mon, Вы писали:
V>>Что означает, что у F(T) несомненно ДРУГОЕ представление в памяти, т.е. памяти может потребоваться больше.
DM>Обычно так, но в некоторых языках бывают и исключения. Например, в Расте Box<T> и Option<Box<T>> представлены в памяти одинаково, потому что первый не может быть нулем, а второй это значение и использует в качестве None.
Ну, любой ссылочный тип у нас имеет T+1, потому что мы храним как значение T, так и ссылку на него.
Если в Расте Box<T> не может быть NULL, то получаем формулу T+1-1 ))
Прикольно, что я именно и предложил использовать боксирование в кач-ве трюка для Optional<T> здесь:
http://www.rsdn.org/forum/philosophy/6705306.1
потому что ссылочный класс изкаробки обладает nullable семантикой.
Ну и попутно заметил, что для ссылочных классов многократное "оборачивание" null не требуется.
Ну и симметрично там же преобразование из ссылочного "опасного" nullable в "строгую" ссылку.
"У дураков мысли сходятся, смотрю" (С)
V>>Только какие проблемы повторить тоже самое с ссылочными (nullable) типами в том же дотнете или C++?
DM>Никаких проблем, повторяют.
Да. В С++ такая идиома ничего не стоит в рантайм:
template<class T>
class NotNull {
T * ptr_;
static T* check(T* ptr) {
if(ptr) return ptr;
throw NullPointerException("ptr");
}
public:
NotNull(T * ptr) : ptr_(check(ptr)) {}
T* operator->() {
T* ptr = ptr_;
__assume(ptr);
return ptr;
}
};
void foo(NotNull<int> x) {}
void bar(NotNull<int> x) { foo(x); }
Причем, из-за __assume оно местами работает быстрее, чем на голых указателях.
Ну и отсутствие необходимости проверок каждый раз. Проверка будет сделана лишь однажды — когда в первый раз будет сконструирован NotNull из голого указателя. Далее всё работает без проверок, распространяя гарантии "строгости" сколь угодно далеко, как в вызове foo(x) из bar.