我对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::<int>(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();
}
Run Code Online (Sandbox Code Playgroud)
这会编译并具有所需的行为,但我不知道该做什么 - 显然我不了解最佳实践或如何实现它们.
编辑:这是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();
}
Run Code Online (Sandbox Code Playgroud)
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);
Run Code Online (Sandbox Code Playgroud)
对于类似的简单类型Person,在Rust中使用struct literal语法创建该类型的实例是惯用的:
let first_person = Person {
name: ~"Ohai",
age: get_int_from_input("Please enter a number for age.")
};
Run Code Online (Sandbox Code Playgroud)
如果你想要一个构造函数,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/ deleteC++中进行操作.但是,与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`.
Run Code Online (Sandbox Code Playgroud)
Option<T>::expect该Option<T>::expect方法是您拥有的匹配语句的惯用快捷方式,x如果您收到Some(x)或未通过消息,您希望返回该方法None.
return在Rust中,它是惯用的(遵循像Haskell和OCaml这样的函数式语言的示例)来返回值而不显式编写return语句.实际上,函数的返回值是函数中最后一个表达式的结果,除非表达式后跟一个分号(在这种情况下它返回(),也就是unit,它本质上是一个空的占位符值 - ()也是什么由没有显式返回类型的函数返回,例如mainor print_info).
无论如何,我不是Rust的伟大专家.如果您需要有关Rust的任何帮助,除了Stack Overflow之外,您还可以尝试irc.mozilla.org上的#rust IRC频道或Rust subreddit.
| 归档时间: |
|
| 查看次数: |
761 次 |
| 最近记录: |