fn average(values: &[f64]) -> f64 {
let total = values.iter().sum::<f64>();
total / values.len() as f64
}
只有一些标准库的特定类型可以用as
可能会丢失精度,因为会截断
From
rust复制代码
impl From<&str> for Person {
fn from(s: &str) -> Person {
let parts = s.split(',').collect::<Vec <&str>>();
if parts.len() != 2 {
return Self::default();
}
if parts[0] == "" {
return Self::default();
}
if let Err(_) = parts[1].parse::<usize>(){
return Self::default();
}
Person{ name : parts[0].to_string() , age : parts[1].parse::<usize>().unwrap()}
}
}
只能返回Self,无法进行错误处理
上文如果发现非法字符只能返回默认选项
FromStr
rust复制代码
impl FromStr for Person {
type Err = ParsePersonError;
fn from_str(s: &str) -> Result<Person, Self::Err> {
if s.len() == 0 {
return Err(ParsePersonError::Empty);
}
let parts = s.split(',').collect::<Vec <&str>>();
if parts.len() != 2 {
return Err(ParsePersonError::BadLen);
}
if parts[0] == "" {
return Err(ParsePersonError::NoName);
}
if let Err(x) = parts[1].parse::<usize>(){
return Err(ParsePersonError::ParseInt(x));
}
Ok(Person{ name : parts[0].to_string() , age : parts[1].parse::<usize>().unwrap()})
}
}
特指字符串转换为其它类型
实现后可以调用parse< T >()方法,用于将字符串转换为指定类型
TryFrom
rust复制代码
impl TryFrom<(i16, i16, i16)> for Color {
type Error = IntoColorError;
fn try_from(tuple: (i16, i16, i16)) -> Result<Self, Self::Error> {
if tuple.0 > 255 || tuple.0 < 0 || tuple.1 > 255 || tuple.1 < 1 || tuple.2 > 255 || tuple.2 < 1{
return Err(Self::Error::IntConversion);
}
Ok(Self{red : tuple.0 as u8, green : tuple.1 as u8, blue : tuple.2 as u8})
}
}
// Array implementation
impl TryFrom<[i16; 3]> for Color {
type Error = IntoColorError;
fn try_from(arr: [i16; 3]) -> Result<Self, Self::Error> {
let mut p = 0;
for x in arr.iter() {
if *x > 255 || *x < 1{
return Err(Self::Error::IntConversion);
}
p += 1;
}
if p != 3 {
return Err(Self::Error::BadLen);
}
Ok(Self{red : arr[0] as u8, green : arr[1] as u8, blue : arr[2] as u8})
}
}
// Slice implementation
impl TryFrom<&[i16]> for Color {
type Error = IntoColorError;
fn try_from(slice: &[i16]) -> Result<Self, Self::Error> {
if slice.len() != 3 {
return Err(Self::Error::BadLen);
}
for x in slice.iter() {
if *x > 255 || *x < 1{
return Err(Self::Error::IntConversion);
}
}
Ok(Self{red : slice[0] as u8, green : slice[1] as u8, blue : slice[2] as u8})
}
}
fn byte_counter<T : AsRef<str>>(arg: T) -> usize {
arg.as_ref().as_bytes().len()
}
// Obtain the number of characters (not bytes) in the given argument.
// TODO: Add the AsRef trait appropriately as a trait bound.
fn char_counter<T : AsRef<str>>(arg: T) -> usize {
arg.as_ref().chars().count()
}
// Squares a number using as_mut().
// TODO: Add the appropriate trait bound.
fn num_sq<T : AsMut<u32>>(arg: &mut T) {
// TODO: Implement the function body.
let mut x = arg.as_mut();
*x *= *x;
}
两者分别对应两个方法:
as_ref,根据特性约束中的泛型,返回对应泛型的不可变引用(第一个函数返回了一个&str)
as_mut,返回可变引用。
rust复制代码
fn foo<T: AsRef<str> + AsRef<[u8]>>(arg: T) {
let s: &str = arg.as_ref();
let bytes: &[u8] = arg.as_ref();
// ...可以同时使用
}