我对Rust非常非常新,并试图实现一些简单的东西来感受语言.现在,我绊倒了实现类似类的结构的最佳方法,该结构涉及将字符串转换为int.我正在使用全局命名空间的函数,我觉得我的红宝石大脑感觉不对.
这样做的乡村方式是什么?
use std::io; struct Person { name: ~str, age: int } impl Person { fn new(input_name: ~str) -> Person { Person { name: input_name, age: get_int_from_input(~"Please enter a number for age.") } } fn print_info(&self) { println(fmt!("%s is %i years old.", self.name, self.age)); } } fn get_int_from_input(prompt_message: ~str) -> int { println(prompt_message); let my_input = io::stdin().read_line(); let my_val = match from_str::(my_input) { Some(number_string) => number_string, _ => fail!("got to put in a number.") }; return my_val; } fn main() { let first_person = Person::new(~"Ohai"); first_person.print_info(); }
这会编译并具有所需的行为,但我不知道该做什么 - 显然我不了解最佳实践或如何实现它们.
编辑:这是0.8
这是我的代码版本,我更加惯用:
use std::io; struct Person { name: ~str, age: int } impl Person { fn print_info(&self) { println!("{} is {} years old.", self.name, self.age); } } fn get_int_from_input(prompt_message: &str) -> int { println(prompt_message); let my_input = io::stdin().read_line(); from_str::<int>(my_input).expect("got to put in a number.") } fn main() { let first_person = Person { name: ~"Ohai", age: get_int_from_input("Please enter a number for age.") }; first_person.print_info(); }
fmt!
/format!
首先,Rust正在弃用fmt!
宏,使用printf
基于语法的语言format!
,而使用类似于Python格式字符串的语法.新版本的Rust 0.9将抱怨使用fmt!
.因此,你应该更换fmt!("%s is %i years old.", self.name, self.age)
使用format!("{} is {} years old.", self.name, self.age)
.但是,我们有一个方便的宏println!(...)
,意味着完全相同的东西println(format!(...))
,所以在Rust中编写代码的最惯用的方法是
println!("{} is {} years old.", self.name, self.age);
对于类似的简单类型Person
,在Rust中使用struct literal语法创建该类型的实例是惯用的:
let first_person = Person { name: ~"Ohai", age: get_int_from_input("Please enter a number for age.") };
如果你想要一个构造函数,Person::new
是一个类型的'默认'构造函数(我指的是最常用的构造函数)的惯用名Person
.但是,默认构造函数要求从用户输入初始化似乎很奇怪.通常,我认为你会有一个person
模块,例如(person::Person
由模块导出).在这种情况下,我认为使用模块级函数是最惯用的fn person::prompt_for_age(name: ~str) -> person::Person
.或者,您可以在Person
- 上使用静态方法Person::prompt_for_age(name: ~str)
.
&str
与~str
函数参数我已经改变了的签名get_int_from_input
采取&str
代替~str
.~str
表示在交换堆中分配一个字符串-换句话说,该堆malloc
/ free
在C,或new
/ delete
C++中进行操作.但是,与C/C++不同,Rust强制要求交换堆上的值一次只能由一个变量拥有.因此,将a ~str
作为函数参数意味着函数的调用者不能重用~str
它传入的参数 - 它必须复制~str
使用该.clone
方法.
另一方面,&str
是字符串中的切片,它只是对字符串中一系列字符的引用,因此在调用带&str
参数的函数时,不需要分配新的字符串副本.
使用的原因&str
,而不是~str
用于prompt_message
在get_int_from_input
是该功能不需要守住过去的函数结束的消息.它只使用提示信息来打印它(并println
采用a &str
而不是a ~str
).一旦你改变了要使用的函数&str
,就可以调用它get_int_from_input("Prompt")
来代替它get_int_from_input(~"Prompt")
,这样可以避免"Prompt"
在堆上进行不必要的分配(同样,你可以避免s
在下面的代码中克隆):
let s: ~str = ~"Prompt"; let i = get_int_from_input(s.clone()); println(s); // Would complain that `s` is no longer valid without cloning it above // if `get_int_from_input` takes `~str`, but not if it takes `&str`.
Option<T>::expect
该Option<T>::expect
方法是您拥有的匹配语句的惯用快捷方式,x
如果您收到Some(x)
或未通过消息,您希望返回该方法None
.
return
在Rust中,它是惯用的(遵循像Haskell和OCaml这样的函数式语言的示例)来返回值而不显式编写return
语句.实际上,函数的返回值是函数中最后一个表达式的结果,除非表达式后跟一个分号(在这种情况下它返回()
,也就是unit,它本质上是一个空的占位符值 - ()
也是什么由没有显式返回类型的函数返回,例如main
or print_info
).
无论如何,我不是Rust的伟大专家.如果您需要有关Rust的任何帮助,除了Stack Overflow之外,您还可以尝试irc.mozilla.org上的#rust IRC频道或Rust subreddit.