Αλεχ
спасибо
Alex
да в той же джаве постоянно List l = ArrayList<> ..., где List — интерфейс, а у l нет явного типа
Ну в Ждаве это исторический костыль, затыкающий невозможность передать ссылку на метод.
Cat
мне, если честно, казалось, что эта функциональность не для этого придумана; ну да ладно
Alex
:)))
Alex
Спасибо, товарищи. Вроде осознал.
Alex
Одно осталось не ясным.
Alex
Если в качестве возвращаемого типа генерится тип-обёртка, реализующий указанный трейт, то каким образом он далее разворачивается, если далее этот тип считается исходным? Например при fn()-> impl Iterator<Item=&i32>{ [42].iter() } вернётся "тайно-магически-сгенерённая" обёртка-итератор, содержащий результат от [42].iter(). Т.е. итератор в итераторе. Так?
Αλεχ
#[no_mangle] pub extern fn foobarbaz() -> impl Fn() -> i32 { || 10 } становится ; Function Attrs: nounwind uwtable define void @foobarbaz() unnamed_addr #1 !dbg !74 { start: ret void, !dbg !78 }
Αλεχ
лентяй даже тип не записывает
Alex
Или вернётся исходный - именно тот, что вернулся из [42].iter() ?
Αλεχ
-
шо это значит?:D
Cat
шо это значит?:D
это видимо всеми любимое "^this"
Αλεχ
это видимо всеми любимое "^this"
хЗ, больше похоже на "вы не правы")
Αλεχ
по крайней мере я минус трактую так
Cat
хЗ, больше похоже на "вы не правы")
это странно, потому что перед этим речь как раз об анонимных классах
Αλεχ
так я вот и спросил поэтому
Αλεχ
задница какая-то нарисована
Αλεχ
доктор, что со мной?
Cat
задница какая-то нарисована
короче реплаем ошибся человек
Cat
чё пристал
Αλεχ
это ты пристал
Cat
ладн
Alex
исходный
Т.е. структура-обёртка генерится только для Fn?
Cat
а просто "трейт" итератор
Cat
где внутри у него будет Item=... и прочее, что необходимо
Cat
если бы возвращался изначальный тип, то это были бы темплейты из С++, которые генерируют уникальную функцию для каждого типа
Alex
Я понял про всё кроме функций (не ||{})
պլհկ
но Fn это не функция
պլհկ
а ||{}
պլհկ
функция это fn
Alex
Пример: fn foo() -> impl Fn { fn inner()->(){} inner } let what_type = foo();
Cat
Fn трейт разве?
պլհկ
да
Cat
воу, пора спать точно
Alex
Что в what_type и что там реально будет лежать?
Alex
Fn трейт разве?
Пишу на телефоне. Могу тупануть.
պլհկ
function pointer
Alex
Αλεχ
#[no_mangle] pub extern fn foobarbaz() -> impl Fn() -> i32 { || 10 } становится ; Function Attrs: nounwind uwtable define void @foobarbaz() unnamed_addr #1 !dbg !74 { start: ret void, !dbg !78 }
Αλεχ
видим, что impl fn становится unnamed_addr #1
Αλεχ
кстати удобно no_mangle использовать, чтобы в LLVM находить нужную функцию
Alex
Круто. Теперь понял!
Alex
Спасибо!
Αλεχ
да всегда пожалуйста :D
Αλεχ
я вот научился LLVM компилятором пользоваться пока разбирался
Alex
А можно ещё вопрос? - это риторически вопрос. Всё равно спрошу.
Alex
Кто может для идиота по русски разъяснить в какой момент статик диспатч превращается в дайнамик? Например let foo :AsRef<_> = something; foo.as_ref(); let bar :&mut AsRef<_> = something_else; bar.as_ref(); fn foo_fn<T>(foo: AsRef<T>) { foo.as_ref(); } fn oof_fn<T>(foo: &AsRef<T>) { foo.as_ref(); } Что здесь is dynamic dispatch and why?
Αλεχ
Пусть меня поправят, если я ошибаюсь
Αλεχ
но динамик диспатч происходит если ты передаешь трейт объект
Αλεχ
это любой бокс на трейт
Αλεχ
и передача через трейт параметр
Cat
а я думал статик это fn<T: Clone> a(t: T), а динамик это fn a(t: &Clone)
Αλεχ
ЯТП в первых двух случаях компилятор будет достаточно умный чтобы соптимизировать, а при вызове функций он передает трейт объект, значит в последних двух будет динамика
Αλεχ
ну это то же, что я и сказал
Cat
ну ок, значит очень сильно туплю
Αλεχ
когда ты делаешь t: T
Αλεχ
у тебя компилятор генерирует для каждого типа нужную перегрузку
Αλεχ
где передается конкретная структура
Cat
стой, я-то не против
Αλεχ
которая естественно статика
Αλεχ
а когда &Clone - одна функция которая принимает динамический объект
Αλεχ
в ООП у тебя объект хранит в себе инфу о типе
Αλεχ
так работают виртуальные вызовы