fn helper<'a, 'b, T>(_: &'a &'b (), v: &'b T) -> &'a T { v }
/// Turn any `&T` into a `&'static T`. May introduce undefined behavior.
pub fn make_static<'a, T>(input: &'a T) -> &'static T {
let f: fn(_, &'a T) -> &'static T = helper;
f(&&(), input)
}
(
отсюдаНе ожидал, что так просто. Безо всякого unsafe берем и превращаем "одолженную"
(
Read more... )
Пока мы оперируем отношением равенства типов, то тип функции выглядит просто:
- вот параметры
- вот фиксированные имена
- а теперь сопоставляйте
По степени навороченности можем взять шкалу от голого си до хаскелла с его многоранговыми типами.
Добавляем отношения субклассов - начинается веселуха. Это и ко-контра-вариантность константности, и наследование... и время жизни тоже.
И тип функции уже становится интереснее:
- вот параметры
- вот имена
- а вот жырный-прежырный предикат, который связывает параметры между собой
И ещё и между типами функций возникают отношения субклассов - и, за компанию, пересечении/объединении этих жырных предикатов.
И тут у нас 4 варианта:
1) принудительно ограничиться какими-то элементарными предикатами (накладывать ограничения на каждый параметр независимо), а что не влезло - отдавать проверкам в рантайме и статических анализаторах
2) тащить предикат неявно (как это в С++) на стороне компилятора, "скомпилится или нет", но мы пожертвуем раздельной компиляцией и всеми прочими плюшками дженериков
3) изобретать магию поверх шаблонов / тайпклассов / фиг знает чего (благо, и те и другие достаточно выразительны)
4) втащить в язык синтаксис и семантику предикатов, достаточно выразительную и при этом не требующую магии из пункта 3
Если раст анонсировал себя как С++ без костылесипедов и с паранойей, то он должен был скатиться к 1 или 4 варианту.
Но не скатился.
Reply
Leave a comment