Rust 中 From trait 定义一个类型如何转换为另一个类型的过程,还有些类似于构造函数。比如最常见的可以将 str 转换为 String
1 2
| let my_str = "hello"; let my_string = String::from(my_str);
|
再比如将一个原始 i32 数字转化为 Number 类型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| use std::convert::From;
#[derive(Debug)] struct Number { value: i32, }
impl From<i32> for Number { fn from(item: i32) -> Self { Number { value: item } } }
fn main() { let num = Number::from(30); println!("My number is {:?}", num); }
|
如果一个类型实现了 From,那么也自动实现了 Into trait,Into 实际上是 From 的逆运算。由于类型可能有多个 From 实现,那么需要具体声明返回值类型。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| use std::convert::From;
#[derive(Debug)] struct Number { value: i32, }
impl From<i32> for Number { fn from(item: i32) -> Self { Number { value: item } } }
fn main() { let int = 5; let num: Number = int.into(); println!("My number is {:?}", num); }
|
在密码学库中,也可以定义私钥到公钥的转换。如下所示,ed25519 的私钥生成中,从私钥获取公钥的过程直接由 let pk: PublicKey = (&sk).into();
一步完成。
具体实现则由 From trait 实现,这样让代码逻辑中的转换实现流程更清晰了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| #[derive(Debug, Default)] pub struct Keypair { pub secret: SecretKey, pub public: PublicKey, } impl KeyPair { pub fn generate<R>(csprng: &mut R) -> Keypair where R: CryptoRng + RngCore, { let sk: SecretKey = SecretKey::generate(csprng); let pk: PublicKey = (&sk).into();
Keypair{ public: pk, secret: sk } } }
#[derive(Default)] pub struct SecretKey(pub(crate) [u8; SECRET_KEY_LENGTH]);
impl AsRef<[u8]> for SecretKey { fn as_ref(&self) -> &[u8] { self.as_bytes() } }
#[derive(Copy, Clone, Default, Eq, PartialEq)] pub struct PublicKey(pub(crate) CompressedEdwardsY, pub(crate) EdwardsPoint);
impl<'a> From<&'a SecretKey> for PublicKey { fn from(secret_key: &SecretKey) -> PublicKey { let mut h: Sha512 = Sha512::new(); let mut hash: [u8; 64] = [0u8; 64]; let mut digest: [u8; 32] = [0u8; 32];
h.input(secret_key.as_bytes()); hash.copy_from_slice(h.result().as_slice());
digest.copy_from_slice(&hash[..32]);
PublicKey::mangle_scalar_bits_and_multiply_by_basepoint_to_produce_public_key(&mut digest) } }
|
代码引用地址:
- https://doc.rust-lang.org/rust-by-example/conversion/from_into.html
- https://github.com/dalek-cryptography/ed25519-dalek/blob/master/src/secret.rs