Можно ли определить, переопределяет ли тип реализацию признака по умолчанию?

#rust

Вопрос:

Здесь у меня есть черта с двумя функциями, обе с реализацией по умолчанию. Есть ли какой-либо способ определить, какие функции имеют реализацию по умолчанию, а какие переопределены для каждого из типов?

https://play.rust-lang.org/?version=stableamp;mode=debugamp;edition=2018amp;gist=f3239e7faa9fb5117e32afe7ae43c687

Я думал, что смогу сравнить адрес функции, но, похоже, каждый тип независимо от этого получает свой собственный уникальный указатель на функцию. Правильно ли я все сделал?

Вы можете спросить, зачем мне вообще понадобилось это делать. Это для системы плагинов. Каждый плагин может переопределять подмножество функций в черте плагина, но при регистрации плагина я хочу знать, какие функции функции реализует плагин (в отличие от просто реализации по умолчанию).

Вероятно, это можно сделать, сделав функцию регистра макрокомандой?

Комментарии:

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> структуру и переданных в нее.