2016-05-22 2 views
9

Предположим, у меня есть код:Как правильно реализовать свойство ToString для структуры?

struct A { 
    names: Vec<String>, 
} 

impl ToString for A { 
    fn to_string(&self) -> String { 
     // code here 
    } 
} 

fn main() { 
    let a = A { names: vec![ 
     "Victor".to_string(), 
     "Paul".to_string(), 
    ]}; 
    println!("A struct contains: [{}].", a.to_string()); 
} 

Ожидаемый результат:

структура содержит: [Виктор, Пол].

Каковы наилучшие пути реализации этого признака для достижения цели с максимальным использованием ржавчины?

Я пробовал некоторые странные «для каждых» и других вещей, но каждый дает мне Запятую, как это:

Виктор, Павел,

Конечно, я могу вытолкнуть его позже, но я Я заинтересован в языке, поэтому я хочу знать, как это сделать. Это всего лишь пример того, что я пробовал, но это не имеет значения, я спрашиваю, как сделать это наиболее эффективно и лучше по значению языка Rust.

P.S. Я изучаю Rust.

ответ

13

Согласно ToStringdocumentation:

Эта черта автоматически применяется для любого типа, который реализует Display черту. Таким образом, ToString не должен быть реализован напрямую: вместо этого необходимо реализовать Display, и вы получите бесплатную реализацию ToString.

Вы можете реализовать Display так:

fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { 
    let mut str = ""; 
    for name in &self.names { 
     try!(fmt.write_str(str)); 
     try!(fmt.write_str(name)); 
     str = ", "; 
    } 
    Ok(()) 
} 

И вам не нужно вызывать to_string (но можно):

fn main() { 
    let a = A { names: vec![ 
     "Victor".to_string(), 
     "Paul".to_string(), 
    ]}; 
    println!("A struct contains: [{}].", a); 
} 

Примечание цель Display:

Display также подобный до Debug, но Display предназначен для вывода пользователя, и поэтому не может быть получен.

Если ваши намерения отладки, вы можете получить Debug:

#[derive(Debug)] 
struct A { 
    names: Vec<String>, 
} 

fn main() { 
    let a = A { names: vec![ 
     "Victor".to_string(), 
     "Paul".to_string(), 
    ]}; 
    // {:?} is used for debug 
    println!("{:?}", a); 
} 

Выходы:

A { names: ["Victor", "Paul"] } 

Formatter структура предлагает богатые коллекции методов, так что вы можете написать свой собственный Debug осуществление:

impl fmt::Debug for A { 
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { 
     fmt.debug_struct("A") 
      .field("names", &self.names) 
      .finish() 
    } 
} 
+0

Все выглядит потрясающе, но я должен заботиться о 'fmt.write_str()' возвращаемом значении? Компилятор жалуется, что результат должен использоваться и дает предупреждение. –

+0

Вы правы. Вызов должен быть обернут ['try!'] (Https: // doc.rust-lang.org/stable/std/macro.try!.html). Я обновил ответ. Благодарю. – malbarbo

+0

Что вы думаете о закрытии как дубликат http://stackoverflow.com/q/22243527/155423? – Shepmaster