Rust學(xué)習(xí)筆記4 面向?qū)ο缶幊?/h1>

github地址:https://github.com/bradyjoestar/rustnotes(歡迎star!)
pdf下載鏈接:https://github.com/bradyjoestar/rustnotes/blob/master/Rust%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0.pdf
參考:
https://rustcc.gitbooks.io/rustprimer/content/ 《RustPrimer》
https://kaisery.github.io/trpl-zh-cn/ 《Rust程序設(shè)計(jì)語(yǔ)言-簡(jiǎn)體中文版》

4.1 面向?qū)ο髷?shù)據(jù)結(jié)構(gòu)

4.1.1 元祖

元祖表示一個(gè)大小浴井、類型固定的有序數(shù)據(jù)組。

let y = (2, "hello world");
let x: (i32, &str) = (3, "world hello");

// 然后呢匙监,你能用很簡(jiǎn)單的方式去訪問(wèn)他們:

// 用 let 表達(dá)式
let (w, z) = y; // w=2, z="hello world"

// 用下標(biāo)

let f = x.0; // f = 3
let e = x.1; // e = "world hello"

Rust雖然函數(shù)只有一個(gè)返回值形庭,只需要通過(guò)元祖月杉,我們可以很容易地返回多個(gè)返回值的組合。例子如下:

pub fn tuple_test1() {
    let (number, persons) = demo_test();
    println!("{}",number);
    println!("{}",persons.name)
}
struct Person {
    name: String,
    age: u16,
}
fn demo_test() -> (u16, Person) {
    let person = Person {
        name: String::from("binwen"),
        age: 12,
    };
    (14,person)
}

4.1.2 結(jié)構(gòu)體

在Rust中贷币,結(jié)構(gòu)體是一個(gè)跟 tuple 類似 的概念简烘。我們同樣可以將一些常用的數(shù)據(jù)、屬性聚合在一起甩恼,就形成了一個(gè)結(jié)構(gòu)體蟀瞧。
所不同的是,Rust的結(jié)構(gòu)體有三種最基本的形式条摸。
1.具名結(jié)構(gòu)體:通常接觸的基本都是這個(gè)類型的悦污。

struct A {
    attr1: i32,
    atrr2: String,
}

內(nèi)部每個(gè)成員都有自己的名字和類型。
2.元祖類型結(jié)構(gòu)體:元組類型結(jié)構(gòu)體

struct B(i32, u16, bool);

它可以看作是一個(gè)有名字的元組钉蒲,具體使用方法和一般的元組基本類似切端。
3.空結(jié)構(gòu)體
結(jié)構(gòu)體內(nèi)部也可以沒(méi)有任何成員。

struct D;

空結(jié)構(gòu)體的內(nèi)存占用為0顷啼。但是我們依然可以針對(duì)這樣的類型實(shí)現(xiàn)它的“成員函數(shù)”踏枣。

4.1.3 結(jié)構(gòu)體的方法

Rust沒(méi)有繼承,它和Golang不約而同的選擇了trait(Golang叫Interface)作為其實(shí)現(xiàn)多態(tài)的基礎(chǔ)钙蒙。

不同的是茵瀑,golang是匿名繼承,rust是顯式繼承躬厌。如果需要實(shí)現(xiàn)匿名繼承的話马昨,可以通過(guò)隱藏實(shí)現(xiàn)類型可以由generic配合trait作出。

struct Person {
    name: String,
}

impl Person {
    fn new(n: &str) -> Person {
        Person {
            name: n.to_string(),
        }
    }

    fn greeting(&self) {
        println!("{} say hello .", self.name);
    }
}

fn main() {
    let peter = Person::new("Peter");
    peter.greeting();
}

上面的impl中,new 被 Person 這個(gè)結(jié)構(gòu)體自身所調(diào)用鸿捧,其特征是 :: 的調(diào)用抢呆,是一個(gè)類函數(shù)! 而帶有 self 的 greeting 笛谦,是一個(gè)成員函數(shù)。

4.1.4 再說(shuō)結(jié)構(gòu)體中引用的生命周期

本小節(jié)例子中昌阿,結(jié)構(gòu)體的每個(gè)字段都是完整的屬于自己的饥脑。也就是說(shuō),每個(gè)字段的 owner 都是這個(gè)結(jié)構(gòu)體懦冰。每個(gè)字段的生命周期最終都不會(huì)超過(guò)這個(gè)結(jié)構(gòu)體灶轰。
但是如果想要持有一個(gè)(可變)引用的值怎么辦?例如

struct RefBoy {
    loc: &i32,
}

則會(huì)得到一個(gè)編譯錯(cuò)誤:

<anon>:6:14: 6:19 error: missing lifetime specifier [E0106]
<anon>:6         loc: & i32,

錯(cuò)誤原因:
這種時(shí)候刷钢,你將持有一個(gè)值的引用笋颤,因?yàn)樗旧淼纳芷谠谶@個(gè)結(jié)構(gòu)體之外,所以對(duì)這個(gè)結(jié)構(gòu)體而言内地,它無(wú)法準(zhǔn)確的判斷獲知這個(gè)引用的生命周期伴澄,這在 Rust 編譯器而言是不被接受的。
這個(gè)時(shí)候就需要我們給這個(gè)結(jié)構(gòu)體人為的寫上一個(gè)生命周期阱缓,并顯式地表明這個(gè)引用的生命周期非凌。這個(gè)引用需要被借用檢查器進(jìn)行檢查。寫法如下:

struct RefBoy<'a> {
    loc: &'a i32,
}

這里解釋一下這個(gè)符號(hào) <>荆针,它表示的是一個(gè) 屬于 的關(guān)系敞嗡,無(wú)論其中描述的是 生命周期 還是 泛型 。即: RefBoy in 'a航背。最終我們可以得出個(gè)結(jié)論喉悴,RefBoy 這個(gè)結(jié)構(gòu)體,其生命周期一定不能比 'a 更長(zhǎng)才行玖媚。
需要知道兩點(diǎn):
1.結(jié)構(gòu)體里的引用字段必須要有顯式的生命周期箕肃。
2.一個(gè)被顯式寫出生命周期的結(jié)構(gòu)體,其自身的生命周期一定小于等于其顯式寫出的任意一個(gè)生命周期最盅。
關(guān)于第二點(diǎn)突雪,其實(shí)生命周期是可以寫多個(gè)的,用 , 分隔涡贱。
注:生命周期和泛型都寫在 <> 里咏删,先生命周期后泛型,用,分隔问词。

一個(gè)比較有趣的例子督函,結(jié)構(gòu)體的遞歸嵌套:

struct Manager {
    name: String,
}

struct Teacher<'res> {
    mana: &'res mut Manager,
}

struct Class<'res: 'row, 'row> {
    teac: &'row mut Teacher<'res>,
}

fn main() {
    let mut m = Manager {
        name: String::from("jojo's"),
    };
    let mut t = Teacher { mana: &mut m };
    let c = Class { teac: &mut t };

    println!("{}", c.teac.mana.name);

    c.teac.mana.name.push_str(" bizarre adverture");

    println!("{}", c.teac.mana.name);

    println!("Hello, world!");
}

4.2.方法

Rust中,通過(guò)impl可以對(duì)一個(gè)結(jié)構(gòu)體添加成員方法。同時(shí)我們也看到了self這樣的關(guān)鍵字辰狡。
impl中的self,常見的有三種形式:self锋叨、 &self、&mut self 宛篇。
雖然方法和golang interface非常相像娃磺,但是還是要加上類似于java的self,主要原因在于Rust的所有權(quán)轉(zhuǎn)移機(jī)制叫倍。
Rust的笑話:“你調(diào)用了一下別人偷卧,然后你就不屬于你了”。
例如下面代碼:

struct A {
    a: i32,
}
impl A {
    pub fn show(self) {
        println!("{}", self.a);
    }
}

fn main() {
    let ast = A{a: 12i32};
    ast.show();
    println!("{}", ast.a);
}

錯(cuò)誤:

13:25 error: use of moved value: `ast.a` [E0382]
<anon>:13     println!("{}", ast.a);

因?yàn)?Rust 本身吆倦,在你調(diào)用一個(gè)函數(shù)的時(shí)候听诸,如果傳入的不是一個(gè)引用,那么無(wú)疑蚕泽,這個(gè)參數(shù)將被這個(gè)函數(shù)吃掉晌梨,即其 owner 將被 move 到這個(gè)函數(shù)的參數(shù)上。同理须妻,impl 中的 self 仔蝌,如果你寫的不是一個(gè)引用的話,也是會(huì)被默認(rèn)的 move 掉璧南。

4.2.1 &self 與 &mut self

關(guān)于 ref 和 mut ref 的寫法和被 move 的 self 寫法類似掌逛,只不過(guò)多了一個(gè)引用修飾符號(hào)。
需要注意的一點(diǎn)是司倚,你不能在一個(gè) &self 的方法里調(diào)用一個(gè) &mut ref 豆混,任何情況下都不行!

#[derive(Copy, Clone)]
struct A {
    a: i32,
}
impl A {
    pub fn show(&self) {
        println!("{}", self.a);
        // compile error: cannot borrow immutable borrowed content `*self` as mutable
        // self.add_one();
    }
    pub fn add_two(&mut self) {
        self.add_one();
        self.add_one();
        self.show();
    }
    pub fn add_one(&mut self) {
        self.a += 1;
    }
}

fn main() {
    let mut ast = A{a: 12i32};
    ast.show();
    ast.add_two();
}

需要注意的是动知,一旦你的結(jié)構(gòu)體持有一個(gè)可變引用皿伺,你,只能在 &mut self 的實(shí)現(xiàn)里去改變他盒粮!例子:

struct Person<'a>{
    name :&'a mut Vec<i32>,
}

impl<'a> Person<'a>{
    fn println_name(&mut self){
        self.name.push(2090);
        println!("{:?}",self.name);
    }

    fn println_name2(&self){
        println!("{:?}",self.name);
    }

    // error[E0596]: cannot borrow `*self.name` as mutable, as it is behind a `&` reference
    //  --> src/trait_test.rs:19:9
    //   |
    //18 |     fn println_name3(&self){
    //   |                      ----- help: consider changing this to be a mutable reference: `&mut self`
    //19 |         self.name.push(2090);
    //   |         ^^^^^^^^^ `self` is a `&` reference, so the data it refers to cannot be borrowed as mutable
    // fn println_name3(&self){
    //     self.name.push(2090);
    //     println!("{:?}",self.name);
    // }
}


pub fn trait_test1(){
    println!("trait_test1");

    let mut a = vec![1,2,3,4];
    let mut person = Person{
        name:&mut a,
    };
    person.name.push(120);

    person.println_name();
    person.println_name2();

    let a = &person;
    println!("{:?}",a.name);
    
    // cannot borrow `*a.name` as mutable, as it is behind a `&` reference
    // a.name.push(200);
    //let a = &person;
    //|             ------- help: consider changing this to be a mutable reference: `&mut person`
    //45 |     println!("{:?}",a.name);
    //46 |     a.name.push(200);
    //|     ^^^^^^ `a` is a `&` reference, so the data it refers to cannot be borrowed as mutable

}

但是你可以在&self 的方法中讀取它鸵鸥。類似于如果一個(gè)結(jié)構(gòu)體持有一個(gè)可變引用A,必須通過(guò)結(jié)構(gòu)體的可變引用去改變A引用的值丹皱,而不能通過(guò)結(jié)構(gòu)體的不可變引用去改變A引用的值妒穴,但是可以通過(guò)結(jié)構(gòu)體的不可變引用去讀取A引用的值。
稍微復(fù)雜的例子:


use std::fmt::Display;

fn longest_with_an_announcement<'a, T>(x: &'a str, y: &'a str, ann: T) -> &'a str
    where T: Display
{
    println!("Announcement! {}", ann);
    if x.len() > y.len() {
        x
    } else {
        y
    }
}

上面了例子引出本章重要的一部分內(nèi)容:trait摊崭。

4.3.trait

trait的簡(jiǎn)單使用:使用trait定義一個(gè)特征(可以定義多個(gè)):

trait HasArea {
    fn area(&self) -> f64;
}

trait里面的函數(shù)可以沒(méi)有(也可以有)函數(shù)體讼油,實(shí)現(xiàn)代碼交給具體實(shí)現(xiàn)它的類型去補(bǔ)充:

struct Circle {
    x: f64,
    y: f64,
    radius: f64,
}

impl HasArea for Circle {
    fn area(&self) -> f64 {
        std::f64::consts::PI * (self.radius * self.radius)
    }
}

fn main() {
    let c = Circle {
        x: 0.0f64,
        y: 0.0f64,
        radius: 1.0f64,
    };
    println!("circle c has an area of {}", c.area());
}

4.3.1 泛型參數(shù)約束

我們知道泛型可以指任意類型,但有時(shí)這不是我們想要的呢簸,需要給它一些約束矮台。

use std::fmt::Debug;
fn foo<T: Debug>(s: T) {
    println!("{:?}", s);
}

Debug是Rust內(nèi)置的一個(gè)trait乏屯,為"{:?}"實(shí)現(xiàn)打印內(nèi)容,函數(shù)foo接受一個(gè)泛型作為參數(shù)瘦赫,并且約定其需要實(shí)現(xiàn)Debug辰晕。
可以使用多個(gè)trait對(duì)泛型進(jìn)行約束:

use std::fmt::Debug;
fn foo<T: Debug + Clone>(s: T) {
    s.clone();
    println!("{:?}", s);
}

<T: Debug + Clone>中Debug和Clone使用+連接,標(biāo)示泛型T需要同時(shí)實(shí)現(xiàn)這兩個(gè)trait确虱。

4.3.1.1泛型參數(shù)約束簡(jiǎn)化(通過(guò)where)

use std::fmt::Debug;
fn foo<T: Clone, K: Clone + Debug>(x: T, y: K) {
    x.clone();
    y.clone();
    println!("{:?}", y);
}

// where 從句
fn foo<T, K>(x: T, y: K) where T: Clone, K: Clone + Debug {
    x.clone();
    y.clone();
    println!("{:?}", y);
}

// 或者
fn foo<T, K>(x: T, y: K)
    where T: Clone,
          K: Clone + Debug {
    x.clone();
    y.clone();
    println!("{:?}", y);
}

4.3.2 trait與內(nèi)置類型

內(nèi)置類型如:i32, i64等也可以添加trait實(shí)現(xiàn)含友,為其定制一些功能:

trait HasArea {
    fn area(&self) -> f64;
}

impl HasArea for i32 {
    fn area(&self) -> f64 {
        *self as f64
    }
}

5.area();

這樣的做法是有限制的。Rust 有一個(gè)“孤兒規(guī)則”:當(dāng)你為某類型實(shí)現(xiàn)某 trait 的時(shí)候校辩,必須要求類型或者 trait 至少有一個(gè)是在當(dāng)前 crate 中定義的唱较。你不能為第三方的類型實(shí)現(xiàn)第三方的 trait 。
在調(diào)用 trait 中定義的方法的時(shí)候召川,一定要記得讓這個(gè) trait 可被訪問(wèn)。

4.3.3 trait默認(rèn)實(shí)現(xiàn)

trait Foo {
    fn is_valid(&self) -> bool;

    fn is_invalid(&self) -> bool { !self.is_valid() }
}

is_invalid是默認(rèn)方法胸遇,F(xiàn)oo的實(shí)現(xiàn)者并不要求實(shí)現(xiàn)它荧呐,如果選擇實(shí)現(xiàn)它,會(huì)覆蓋掉它的默認(rèn)行為纸镊。

4.3.4 trait的繼承

trait Foo {
    fn foo(&self);
}

trait FooBar : Foo {
    fn foobar(&self);
}

這樣FooBar的實(shí)現(xiàn)者也要同時(shí)實(shí)現(xiàn)Foo:

struct Baz;

impl Foo for Baz {
    fn foo(&self) { println!("foo"); }
}

impl FooBar for Baz {
    fn foobar(&self) { println!("foobar"); }
}

必須顯式實(shí)現(xiàn)Foo倍阐,這種寫法是錯(cuò)誤的:

impl FooBar for Baz {
    fn foobar(&self) { println!("foobar"); }

//    --> src/trait_test_three.rs:18:5
//    |
//    18 |     fn foo(&self) { println!("foo"); }
//    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not a member of trait `FooBar`

//    fn foo(&self) { println!("foo"); }
}

4.3.5 derive屬性

Rust提供了一個(gè)屬性derive來(lái)自動(dòng)實(shí)現(xiàn)一些trait,這樣可以避免重復(fù)繁瑣地實(shí)現(xiàn)他們逗威,能被derive使用的trait包括:Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd

#[derive(Debug)]
struct Foo;

fn main() {
    println!("{:?}", Foo);
}

4.3.6 impl Trait

impl Trait 語(yǔ)法適用于短小的例子峰搪,它不過(guò)是一個(gè)較長(zhǎng)形式的語(yǔ)法糖。這被稱為 trait bound.使用場(chǎng)景如下:

1.傳參數(shù)

// before
fn foo<T: Trait>(x: T) {

// after
fn foo(x: impl Trait) {

2.返回參數(shù)

fn returns_summarizable() -> impl Summary {
    Tweet {
        username: String::from("horse_ebooks"),
        content: String::from("of course, as you probably already know, people"),
        reply: false,
        retweet: false,
    }
}

這個(gè)簽名表明凯旭,“我要返回某個(gè)實(shí)現(xiàn)了 Summary trait 的類型概耻,但是不確定其具體的類型”。在例子中返回了一個(gè) Tweet罐呼,不過(guò)調(diào)用方并不知情鞠柄。

  1. 使用trait bound有條件地實(shí)現(xiàn)方法
    通過(guò)使用帶有 trait bound 的泛型參數(shù)的 impl 塊,可以有條件地只為那些實(shí)現(xiàn)了特定 trait 的類型實(shí)現(xiàn)方法嫉柴。例如厌杜,下面例子中的類型 Pair<T> 總是實(shí)現(xiàn)了 new 方法,不過(guò)只有那些為 T 類型實(shí)現(xiàn)了PartialOrd trait (來(lái)允許比較) 和 Display trait (來(lái)啟用打蛹坡荨)的 Pair<T> 才會(huì)實(shí)現(xiàn) cmp_display方法:
use std::fmt::Display;

struct Pair<T> {
    x: T,
    y: T,
}

impl<T> Pair<T> {
    fn new(x: T, y: T) -> Self {
        Self {
            x,
            y,
        }
    }
}

impl<T: Display + PartialOrd> Pair<T> {
    fn cmp_display(&self) {
        if self.x >= self.y {
            println!("The largest member is x = {}", self.x);
        } else {
            println!("The largest member is y = {}", self.y);
        }
    }

4.閉包

// before
fn foo() -> Box<Fn(i32) -> i32> {
    Box::new(|x| x + 1)
}

// after
fn foo() -> impl Fn(i32) -> i32 {
    |x| x + 1
}

4.3.7 trait對(duì)象

此外夯尽,trait高級(jí)用法還有trait對(duì)象等等。這部分請(qǐng)查閱rustPrimer相應(yīng)章節(jié)登馒。

4.3.8 trait定義中的生命周期和可變性聲明

trait特性中的可變性和生命周期泛型定義必須和實(shí)現(xiàn)它的方法完全一致匙握!不能缺省谊娇!

例子:

trait HelloArea{
    fn areas<'a>(&mut self, a:&'a mut Vec<i32>, b:&'a mut Vec<i32>) -> &'a mut Vec<i32>;
}

struct Circle {
    x: f64,
    y: f64,
    radius: f64,
}

impl HasArea for Circle {
    fn area(&self) -> f64 {
        std::f64::consts::PI * (self.radius * self.radius)
    }
}

impl HelloArea for Circle{
    fn areas<'a>(&mut self, a:&'a mut Vec<i32>, b:&'a mut Vec<i32>) -> &'a mut Vec<i32>{
        a.push(10000);
        return a;
    }
}

//compile_error!()

//error[E0053]: method `area` has an incompatible type for trait
//  --> src/trait_test_two.rs:23:13
//   |
//13 |     fn area(&mut self) -> f64;
//   |             --------- type in trait
//...
//23 |     fn area(&self) -> f64 {
//   |             ^^^^^ types differ in mutability

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者

  • 序言:七十年代末肺孤,一起剝皮案震驚了整個(gè)濱河市罗晕,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌赠堵,老刑警劉巖小渊,帶你破解...
    沈念sama閱讀 219,539評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異茫叭,居然都是意外死亡酬屉,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,594評(píng)論 3 396
  • 文/潘曉璐 我一進(jìn)店門揍愁,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)呐萨,“玉大人,你說(shuō)我怎么就攤上這事莽囤∶粒” “怎么了?”我有些...
    開封第一講書人閱讀 165,871評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵朽缎,是天一觀的道長(zhǎng)惨远。 經(jīng)常有香客問(wèn)我,道長(zhǎng)话肖,這世上最難降的妖魔是什么北秽? 我笑而不...
    開封第一講書人閱讀 58,963評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮最筒,結(jié)果婚禮上贺氓,老公的妹妹穿的比我還像新娘。我一直安慰自己床蜘,他們只是感情好辙培,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,984評(píng)論 6 393
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著邢锯,像睡著了一般虏冻。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上弹囚,一...
    開封第一講書人閱讀 51,763評(píng)論 1 307
  • 那天厨相,我揣著相機(jī)與錄音,去河邊找鬼鸥鹉。 笑死蛮穿,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的毁渗。 我是一名探鬼主播践磅,決...
    沈念sama閱讀 40,468評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼灸异!你這毒婦竟也來(lái)了府适?” 一聲冷哼從身側(cè)響起羔飞,我...
    開封第一講書人閱讀 39,357評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎檐春,沒(méi)想到半個(gè)月后逻淌,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,850評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡疟暖,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,002評(píng)論 3 338
  • 正文 我和宋清朗相戀三年卡儒,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片俐巴。...
    茶點(diǎn)故事閱讀 40,144評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡骨望,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出欣舵,到底是詐尸還是另有隱情擎鸠,我是刑警寧澤,帶...
    沈念sama閱讀 35,823評(píng)論 5 346
  • 正文 年R本政府宣布缘圈,位于F島的核電站糠亩,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏准验。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,483評(píng)論 3 331
  • 文/蒙蒙 一廷没、第九天 我趴在偏房一處隱蔽的房頂上張望糊饱。 院中可真熱鬧,春花似錦颠黎、人聲如沸另锋。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,026評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)夭坪。三九已至,卻和暖如春过椎,著一層夾襖步出監(jiān)牢的瞬間室梅,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,150評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工疚宇, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留亡鼠,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,415評(píng)論 3 373
  • 正文 我出身青樓敷待,卻偏偏與公主長(zhǎng)得像间涵,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子榜揖,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,092評(píng)論 2 355