< 返回我的博客

套路小迷糊 发表于 2018-03-29 13:04

笔者知道很多新手都会和Rust的字符串类型周旋很长的一段时间。因为很多人都是从这里第一次实践什么叫做所有权系统的。以至于所有权系统没搞懂、编译原理不清楚以及汇编语言完全不会的情况下很多人都容易在这里放弃Rust语言。笔者写这篇文章就是为了扫清障碍来拯救您的。

新手友好的 String 类型

很多自称能搞懂Rust的字符串类型的新手,实际上连所有权系统都搞不懂。实际上他们只是用了 String 类型。其实在一般的程序,特别是那些对速度要求不那么严格的程序里面用 String 克隆来克隆去也没什么。所以这个类型推荐给所有刚刚开始学习Rust的新手使用。为了避免出错,直接把所有 &str 类型转成 String 就可以了。需要用 &str 的时候再临时转回来,简直美滋滋。

这里有一个例子:

#[allow(dead_code)]
enum Gender {
    Male,
    Female,
    Secret,
    Else,
}

struct Person {
    name: String,
    gender: Gender,
}

impl Person {
    fn new(name: String, gender: Gender) -> Self {
        Person {
            name: name,
            gender: gender,
        }
    }

    fn new_guy(name: String) -> Self {
        Person::new(name, Gender::Male)
    }

    fn new_lady(name: String) -> Self {
        Person::new(name, Gender::Female)
    }

    fn comfortable(&self) -> String {
        match self.gender {
            Gender::Male => self.name.clone() + ",你很安逸呀",
            _ => "此时此刻的".to_string() + &*self.name + "感到安逸",
        }
    }
}

fn main() {
    let cool_guy = Person::new_guy("靓仔".to_string());
    println!("{}", cool_guy.comfortable());
    let myself = Person::new_lady("刘祺".to_string());
    println!("{}", myself.comfortable());
}

自从用了 String 类型有没有感到生活是多么的美好。然而,如果这样的代码如果和有经验的Rust程序员交流的话,一定会被骂的。而且也不方便向别人介绍Rust有多么好,毕竟每次用个字符串都没玩没了的 to_string 似乎太不友好了。所以呢,我们改良一下:

fn new<T: Into<String>>(name: T, gender: Gender) -> Self {
    Person {
        name: name.into(),
        gender: gender,
    }
}

fn new_guy<T: Into<String>>(name: T) -> Self {
    Person::new(name, Gender::Male)
}

fn new_lady<T: Into<String>>(name: T) -> Self {
    Person::new(name, Gender::Female)
}

调用的时候就不需要没完没了的 to_string 了:

fn main() {
    let cool_guy = Person::new_guy("靓仔");
    println!("{}", cool_guy.comfortable());
    let myself = Person::new_lady("刘祺");
    println!("{}", myself.comfortable());
}

在一般的程序中这差不多就够用了。让我们回忆一下我们都讲解了什么并且补充一些细节。

回顾与细节补充

首先我们有一个 struct 里面有一个字段是字符串,我们就这样写:

struct Person {
    name: String,
    gender: Gender, // Gender 已定义
}

为什么我们这样写呢,因为不这样写我们会遇到 &str,而我们还没有讲和生命周期这些东西如何周旋的问题。譬如您这样写:

struct Person {
    name: &str,
    gender: Gender,
}

就会得到:

error[E0106]: missing lifetime specifier

第一次和生命周期周旋

所以我们暂时为了绕开生命周期就用了 String。这里补充一个细节,如果不想绕开生命周期,就想使用 &str,您可以这样写:

struct Person {
    name: &'static str,
    gender: Gender,
}

阅读全文

评论区

写评论
fishfish 2018-03-30 18:35

nice ,nice ,nice

1 共 1 条评论, 1 页