Если вы новичок в Rust, то трейты `From` и `Into` могут показаться вам запутанными, но это интересные системы характеристик Rust. В этой статье мы будем изучать трейты характеристик на примерах.
Характеристики `From` и `Into` по своей сути связаны, и на самом деле это части реализации трейта. Если вы можете преобразовать тип `A` из типа `B`, то должно быть так же легко преобразовать тип `B` в тип `A`.
Трейт From
Трейт From предоставляет возможность создать характеристику преобразования, он позволяет вам преобразовывать значения одного типа в значения другого типа. Например, стандартная библиотека реализует `impl From<&'_ str> for String`, который позволяет вам генерировать строку из `&str`.
Например, мы можем легко преобразовать срез `&str` в строку:
Другой пример характеристики:
Предположим, мы хотим реализовать нашу собственную характеристику `From<String> for SplitName`. Это позволило бы нам разделить любое заданное имя, разделенное пробелом, на структуру, содержащую имя и фамилию. Это можно легко сделать, используя трейт `From`. Ниже приведен пример того же самого.
Параметр `From` также очень полезен при выполнении обработки ошибок. При построении функции, способной к сбою, возвращаемый тип обычно будет иметь вид `Result<T, E>`.
Примечание: Этот трейт не должен подводить. Характеристика From предназначена для идеальных конверсий. Если преобразование может завершиться неудачей или не является совершенным, используйте TryFrom.
Трейт Into
Трейт `Into` противоположен трейту `From`. Реализация `From` автоматически обеспечивает реализацию трейта `Into`. Следует избегать реализации `Into` и вместо этого внедрять `From` .
Использование характеристики Into обычно требует спецификации типа для преобразования, поскольку компилятор не может определить это большую часть времени.
Например, мы можем легко преобразовать `&str` в строку:
Снова используя приведенный выше пример, чтобы разделить любое заданное имя, разделенное пробелом, на структуру, содержащую имя и фамилию, мы можем разделить имя напрямую, вызвав `.into()` для заданного имени после преобразования его в строку. Здесь мы должны предоставить спецификацию следующим образом: `let into_example: SplitName = "Привет всем".to_string().into();`
Вот полный код для преобразования имени в `SplitName` с использованием характеристик From и Into:
Вы вольны использовать into() и from(), и вам решать, какой из них наиболее выразителен для вашего кода, но предпочитает использовать Into вместо From при указании характеристики для универсальной функции, чтобы гарантировать, что типы, которые реализуют только Into, также могут быть использованы.
Примечание: Этот трейт не должен подводить. Если преобразование может завершиться неудачей, используйте TryInto.
Вывод
Трейты `From` и `Into` в Rust используются для выполнения преобразований типов. Трейт `From` позволяет вам преобразовывать значения одного типа в значения другого типа, реализуя метод `from`. Трейт `Into` является упрощенной версией трейта `From` и позволяет осуществлять более простое преобразование путем реализации метода `into`.
Основное различие между ними заключается в том, что трейт `Into` предполагает, что преобразование всегда будет успешным, в то время как трейт “From” допускает возможность неудачного преобразования, что достигается путем возврата типа результата из реализации метода from, который может быть либо в порядке с преобразованным значением, или ошибка с описанием ошибки.
Статья на list-site.