#rust
Вопрос:
Здесь у меня есть черта с двумя функциями, обе с реализацией по умолчанию. Есть ли какой-либо способ определить, какие функции имеют реализацию по умолчанию, а какие переопределены для каждого из типов?
Я думал, что смогу сравнить адрес функции, но, похоже, каждый тип независимо от этого получает свой собственный уникальный указатель на функцию. Правильно ли я все сделал?
Вы можете спросить, зачем мне вообще понадобилось это делать. Это для системы плагинов. Каждый плагин может переопределять подмножество функций в черте плагина, но при регистрации плагина я хочу знать, какие функции функции реализует плагин (в отличие от просто реализации по умолчанию).
Вероятно, это можно сделать, сделав функцию регистра макрокомандой?
Комментарии:
1. Не могли бы вы вернуть саму функцию признака
Option<fn()>
? Тогда вы могли бы вернуть реализацию признака по умолчаниюNone
, и любые пользовательские реализации вернулисьSome(real_impl_fn)
бы или что-то в этом роде.2. Я мог бы это сделать, но я думаю, что это становится неоптимальным, когда fn асинхронен и требует состояния (общая ссылка на структуру, реализующую плагин).
Ответ №1:
Указатели на функции не будут надежными из-за оптимизации компилятора. Например, при сборке в выпуске вы увидите один и тот же адрес для <C as Foo>::bar
и <C as Foo>::baz
потому, что компилятор объединил их, поскольку они содержат одно и то же тело (игровая площадка)
Макрос может генерировать другие функции, например fn override_foo() -> bool { true }
, и позволяет определить, был ли он переопределен, но для системы плагинов я бы, вероятно, придерживался указателей функций, завернутых в Option<T>
структуру и переданных в нее.