golang snippet first

写在前面的东东:
https://www.golangtc.com/ 然后设置环境变量。
开始是在atom上搞得,发现不能自行编译,学习语法的我觉得好麻烦啊啊啊啊啊!虽然配置好了,但是不想用,真得真的真的推荐goland这个,加上pycharm,idea,clion,vs突然发现我用得ide已经被捷克人给统治了!!!!只有vs还坚挺!最后真心推荐goland!
ps:goland有很多提示,比如,result:

微信图片_20180121023422.png

ps:不要问我怎么破解,我不回告诉你去淘宝买账号,捷克老毛子的软件十块钱通吃~

1.nil

nil在go中相当于其他语言的NULL,null,none等。在实际的使用中,表示某一个变量为空。nil只能赋值给point,channel,func,interface,map或者slice类型的变量。如果将nill赋值给其他变量将会引发panic。

结论:由于go中interface会同时存储类型和值,如果将一个nill对象赋值给一个interface,这个interface为非nill。

package main

import "fmt"

type MyError struct{}

func (this *MyError) Error() string {
    return ""
}

func test() error {
    var p *MyError = nil
    /*
           //Check err and Set p
           if bad() {
               p = ErrBad
           }
    */
    return p
}

func main() {
    err := test()
    if err == nil {
        fmt.Println("err is nil")
    } else {
        fmt.Println("err is NOT nil")
    }
}

结果是:

err is NOT nil

虽然现在这个函数看不懂,先把代码粘贴上。
///引用 https://studygolang.com/articles/5969

2.for

func main() {
    var i,j = 0,100
    for i == 0 {
        fmt.Println("first style")
        i++
    }
    for i = 0;i<=j;i++{
        fmt.Printf("second style %d\n",i)
    }
}

3.函数可以返回多个值


import "fmt"

func swap(x, y string) (string, string) {
   return y, x
}

func main() {
   a, b := swap("Mahesh", "Kumar")
   fmt.Println(a, b)
}

4.函数闭包function closure

func funcclosure() func() int {
    i:=0
    fmt.Println("funcclosure",i)//这里是重点
    return func() int{
        i++
        return i
    }
}
func main() {
    //function closure
    nextnum := funcclosure()
        //调用 nextnum(),变量 i 自增,并返回
    fmt.Println(nextnum())
    fmt.Println(nextnum())
    fmt.Println(nextnum())
    fmt.Println(nextnum())

    nextnum1 := funcclosure()
    fmt.Println(nextnum1())
    fmt.Println(nextnum1())
    fmt.Println(nextnum1())
}

输出

funcclosure 0
1
2
3
4
funcclosure 0
1
2
3

为什么会这样呢?其实nextnum := funcclosure() 这一句,nextnum()就等价于 func(),也就是funcclosure()中返回的那个函数。其实nextnum()每次调用的就是这个func(),所以i每次都会增加1.

5.方法

结构:

func (variable_name variable_data_type) function_name() [return_type]{
   /* 函数体*/
}


func (方法接受者) 方法名字 返回类型{
//函数体
}
方法接受者可以是命名类型或者结构体类型的一个值或者是一个指针。

package main

import "fmt"

type Circle struct {
    radius float64
}
func main(){
    var c1 Circle
    c1.radius = 10.00
    fmt.Println("Area of Circle(c1) = ", c1.getArea())
}

//该method 属于 Circle 类型对象中的方法
func (c Circle) getArea() float64{
    //
    return 3.14 * c.radius * c.radius
}

结果:

Area of Circle(c1) =  314

6.变量作用域

Go 语言程序中全局变量与局部变量名称可以相同,但是函数内的局部变量会被优先考虑。实例如下:

package main
import "fmt"

/* 声明全局变量 */
var g int = 20

func main() {
   /* 声明局部变量 */
   var g int = 10

   fmt.Printf ("结果: g = %d\n",  g)
}
结果: g = 10

7.数组

var variable_name [SIZE] variable_type

初始化数组:

var balance = [5]float32{1000.0, 2.0, 3.4, 7.0, 50.0}

如果忽略 [] 中的数字不设置数组大小,Go 语言会根据元素的个数来设置数组的大小:

var balance = [...]float32{1000.0, 2.0, 3.4, 7.0, 50.0}

数组得访问:

var balance = [...]float32{1000.0, 2.0, 3.4, 7.0, 50.0}
var salary float32= balance[4]
fmt.Println(salary)

多维数组:

var variable_name [SIZE1][SIZE2]...[SIZEN] variable_type

向函数传递数组:

void myFunction(param [10]int)
{
......
}
void myFunction(param []int)
{
.......
}

求平均值:

package main

import "fmt"
func main(){
    var arr = []int{23,19,100,231,51}
    var avg float32
    avg = getAvag(arr,5)
    fmt.Println("平均值为:",avg)

}

func getAvag(arr []int,size int) float32{
    var i,sum int
    var avg float32
    for i=0;i<size;i++{
        sum += arr[i]
    }
    avg = float32(sum / size)

    return avg

}

结果:

平均值为: 84

8.指针

var var_name *var-type
var ip *int        /* 指向整型*/
var fp *float32    /* 指向浮点型 */

一般用法:

package main

import "fmt"

func main(){
    var ptr *int
    fmt.Println("ptr:",ptr)
    fmt.Printf("ptr value :%x\n",ptr)

    var a = 10
    ptr = &a
    fmt.Println("ptr:",ptr)
    fmt.Printf("ptr value :%d\n",*ptr)
    fmt.Printf("ptr value :%x\n",ptr)

    var b = "abc"
    var ptr1 *string
    ptr1 = &b
    fmt.Println("address is:",ptr1)
    fmt.Println("ptr1 value:",*ptr1)
}

结果:

ptr: <nil>
ptr value :0
ptr: 0xc0420080e0
ptr value :10
ptr value :c0420080e0
address is: 0xc0420381c0
ptr1 value: abc

数组与指针:

package main
import "fmt"
func main(){
    //array
    var arr = []int{15,20,25}
    fmt.Println("arr:",arr)
    var i int
    for i=0;i<3;i++{
        fmt.Println("arr:",&arr[i])
    }

}

结果是:

arr: [15 20 25]
arr: 0xc0420500c0
arr: 0xc0420500c8
arr: 0xc0420500d0

和c/c++得指针有相似得地方,也有不同得地方。数组名不是数组首地址,就代表了数组。
指向指针的指针:

package main
import "fmt"

func main(){
    //
    var tmp1 int
    var ptr2 *int
    var ptr3 **int

    tmp1 = 7000
    ptr2 = &tmp1
    ptr3 = &ptr2

    fmt.Println("tmp1:",tmp1)
    fmt.Println("ptr2:",ptr2)
    fmt.Println("*ptr2:",*ptr2)
    fmt.Println("&*ptr2:",&(*ptr2))
    fmt.Println("ptr3:",ptr3)
    fmt.Println("*ptr3:",*ptr3)
    fmt.Println("**ptr3:",**ptr3)
}

结果是:

tmp1: 7000
ptr2: 0xc0420520d0
*ptr2: 7000
&*ptr2: 0xc042008108
ptr3: 0xc042070020
*ptr3: 0xc0420520d0
**ptr3: 7000

指针作为参数:

package main
import "fmt"
func main(){
    var a1,a2 int = 520,250
    fmt.Println("before a1,a2",a1,a2)
    swap(&a1,&a2)
    fmt.Println("atfer a1,a2",a1,a2)
}

func swap(x *int,y *int){
    var temp int
    temp = *x
    *x = *y
    *y = temp
}

结果:

before a1,a2 520 250
atfer a1,a2 250 520

9.结构体:

结构体是由一系列具有相同类型或不同类型的数据构成的数据集合。

type struct_variable_type struct {
   member definition;
   member definition;
   ...
   member definition;
}

声明格式:

variable_name := structure_variable_type {value1, value2...valuen}

如果要访问结构体成员,需要使用点号 (.) 操作符,格式为:"结构体.成员名"。
golang的指针一定要理解清楚。

package main
import "fmt"

type BookInfo struct{
    title string
    author string
    subject string
    book_id int
}

func main(){
    var book1 BookInfo
    var book2 BookInfo
    var book3 BookInfo
        //这个指针只是来存储地址的,类型是BookInfo
    var bookPtr *BookInfo

    book1.title = "Go 语言教程"
    book1.author = "Alpha"
    book1.subject = "Go 语言"
    book1.book_id = 10109527

    book2.title = "Python 教程"
    book2.author = "Alpha"
    book2.subject = "Python 教程"
    book2.book_id = 10109528

    book3.title = "C++ 教程"
    book3.author = "Alpha"
    book3.subject = "C++ 教程"
    book3.book_id = 10109529

    fmt.Println("book1:",book1)
    fmt.Println("book2:",book2)
    fmt.Println("book3:",book3)

    PrintBookInfo(book1)
    PrintBookInfo(book2)
        //一定要这样调用
    bookPtr = &book3
    PrintBookInfoPoint(bookPtr)
}

func PrintBookInfo(book BookInfo){
    fmt.Println("book title:",book.title)
    fmt.Println("book author:",book.author)
    fmt.Println("book subject:",book.subject)
    fmt.Println("book book_id",book.book_id)
}
func PrintBookInfoPoint(book *BookInfo){
    fmt.Println("book title:",book.title)
    fmt.Println("book author:",book.author)
    fmt.Println("book subject:",book.subject)
    fmt.Println("book book_id",book.book_id)
}

结果:

book1: {Go 语言教程 Alpha Go 语言 10109527}
book2: {Python 教程 Alpha Python 教程 10109528}
book3: {C++ 教程 Alpha C++ 教程 10109529}
book title: Go 语言教程
book author: Alpha
book subject: Go 语言
book book_id 10109527
book title: Python 教程
book author: Alpha
book subject: Python 教程
book book_id 10109528
book title: C++ 教程
book author: Alpha
book subject: C++ 教程
book book_id 10109529

10.切片(slice)

Go 语言切片是对数组的抽象。
Go 数组的长度不可改变,在特定场景中这样的集合就不太适用,Go中提供了一种灵活,功能强悍的内置类型切片("动态数组"),与数组相比切片的长度是不固定的,可以追加元素,在追加时可能使切片的容量增大.(抄的 =。=)
格式:

var identifier []type

切片不需要说明长度。
或使用make()函数来创建切片:

var slice1 []type = make([]type, len)
也可以简写为
slice1 := make([]type, len)

也可以指定容量,其中capacity为可选参数。

make([]T, length, capacity)

这里 len 是数组的长度并且也是切片的初始长度。

//初始化
s :=[] int {1,2,3 } 
//接初始化切片,[]表示是切片类型,{1,2,3}初始化值依次是1,2,3.其cap=len=3
s := arr[:] 
//初始化切片s,是数组arr的引用
s := arr[startIndex:endIndex] 
//将arr中从下标startIndex到endIndex-1 下的元素创建为一个新的切片
s := arr[startIndex:]
//缺省endIndex时将表示一直到arr的最后一个元素
s := arr[:endIndex] 
//缺省startIndex时将表示从arr的第一个元素开始
s1 := s[startIndex:endIndex] 
//通过切片s初始化切片s1
s :=make([]int,len,cap) 
//通过内置函数make()初始化切片s,[]int 标识为其元素类型为int的切片

len()与cap():
切片是可索引的,并且可以通过len()方法获取长度。
切片提供了计算容量的方法cap(),可以测量切片最长可以达到多少。

package main

import "fmt"

func main(){
    //len() cap()
    var sl1 = make([]int,3,5)
    var sl2 []int

    printSlice(sl1)
    printSlice(sl2)

    if(sl2 == nil){
        fmt.Println("sl2 切片是空的")
    }
    /*创建切片*/
    sl3 := []int{0,1,2,3,4,5,6,7,8,9}
    printSlice(sl3)

    /*打印原始切片*/
    fmt.Println("sl3 == ",sl3)

    /*打印子切片从索引1到索引4*/
    fmt.Println("sl3[1:4] == ",sl3[1:4])

    /*默认下限为 0*/
    fmt.Println("sl3[:4] == ",sl3[:4])

    /*默认上限为 len(s)*/
    fmt.Println("sl3[4:] == ",sl3[4:])

    sl4 := make([]int,0,5)
    printSlice(sl4)

    /*打印子切片从索引  0(包含) 到索引 2(不包含)*/
        //索引!!!!
    sl5 := sl3[:2]
    printSlice(sl5)

    /* 打印子切片从索引 2(包含) 到索引 5(不包含)*/
        //索引!!!!
    sl6 := sl3[2:5]
    printSlice(sl6)
}

func printSlice(x []int){
    fmt.Printf("len=%d cap=%d slice=%v\n",len(x),cap(x),x)
}

结果是:

len=3 cap=5 slice=[0 0 0]
len=0 cap=0 slice=[]
sl2 切片是空的
len=10 cap=10 slice=[0 1 2 3 4 5 6 7 8 9]
sl3 ==  [0 1 2 3 4 5 6 7 8 9]
sl3[1:4] ==  [1 2 3]
sl3[:4] ==  [0 1 2 3]
sl3[4:] ==  [4 5 6 7 8 9]
len=0 cap=5 slice=[]
len=2 cap=10 slice=[0 1]
len=3 cap=8 slice=[2 3 4]

append()与copy()

package main

import (
    "fmt"
)

func main(){
    var slice1 []int
    printSlice(slice1)

    /*允许住家空切片*/
    slice1 = append(slice1,0)
    printSlice(slice1)

    /*向切片添加一个元素*/
    slice1 = append(slice1,1)
    printSlice(slice1)

    /*同时添加多个元素*/
    slice1 = append(slice1,1,2,3,4,5)
    printSlice(slice1)

    /*创建切片 slice2是之前切片的两倍*/
    slice2 := make([]int,len(slice1),(cap(slice1))*2)
    /*拷贝slice1到slice2*/
    copy(slice2,slice1)
    printSlice(slice2)

}
func printSlice(x []int){
    fmt.Printf("len=%d cap=%d slice=%v\n",len(x),cap(x),x)
}

结果是:

len=3 cap=5 slice=[0 0 0]
len=0 cap=0 slice=[]
sl2 切片是空的
len=10 cap=10 slice=[0 1 2 3 4 5 6 7 8 9]
sl3 ==  [0 1 2 3 4 5 6 7 8 9]
sl3[1:4] ==  [1 2 3]
sl3[:4] ==  [0 1 2 3]
sl3[4:] ==  [4 5 6 7 8 9]
len=0 cap=5 slice=[]
len=2 cap=10 slice=[0 1]
len=3 cap=8 slice=[2 3 4]

11.rang

range关键字用于for循环中迭代数组(array)、切片(slice)、通道(channel)或者集合(map)的元素。在数组中和切片中他返回元素的索引值,在集合中返回key-value对的key值。

package main
import "fmt"
func main() {
    //这是我们使用range去求一个slice的和,使用数组跟这个很类似
    nums := []int{2, 3, 4, 5}
    sum := 0
    for _, num := range nums {
        sum += num
    }
    fmt.Println("sum:", sum)
    //在数组上使用range将传入index和值两个变量。上面的例子不需要使用元素序号,所以可以用空白符代替。
    for i, num := range nums {
        if num == 3 {
            fmt.Println("index:", i)
        }
    }
    //range也可以用在map键值对上。
    kvs := map[string]string{"a": "apple", "b": "banana"}
    for k, v := range kvs {
        fmt.Printf("%s, -> %s\n", k, v)
    }
    //range也可以用来枚举Unicode字符串
    for i,c := range "golang"{
        fmt.Println(i,c)
    }
}

结果是:

sum: 14
index: 1
b, -> banana
a, -> apple
0 103
1 111
2 108
3 97
4 110
5 103

12.Map 集合

map是一种无序的键值对集合,(和python的dict挺像的)。Map是使用hash表来实现的。
可以是用make,也可以使用map来定义。

/* 声明变量,默认 map 是 nil */
var map_variable map[key_data_type]value_data_type

/* 使用 make 函数 */
map_variable := make(map[key_data_type]value_data_type)

如果不初始化 map,那么就会创建一个 nil map。nil map 不能用来存放键值对。

package main

import (
    "fmt"
)

func main(){
    var countryCapitalMap map[string] string
    //创建集合
    countryCapitalMap = make(map[string]string)

    //map 插入`key-value`键值对
    countryCapitalMap["France"] = "Paris"
    countryCapitalMap["Italy"] = "Rome"
    countryCapitalMap["Japan"] = "Tokyo"
    countryCapitalMap["India"] = "New Delhi"
    countryCapitalMap["China"] = "BeiJing"

    for country := range countryCapitalMap{
        fmt.Println("Capital of ",country," is ",countryCapitalMap[country])
    }

    //查看元素在集合中是否存在
    captial,ok := countryCapitalMap["United States"]
    if(ok){
        fmt.Println("Captial of United States is ",captial)
    }else{
        fmt.Println("Capital of United States is not present.")
    }

    delete(countryCapitalMap,"France")
    fmt.Println("Entry for France is deleted.")

    for country := range countryCapitalMap{
        fmt.Println("Capital of ",country," is ",countryCapitalMap[country])
    }
}

结果是:

Capital of  Italy  is  Rome
Capital of  Japan  is  Tokyo
Capital of  India  is  New Delhi
Capital of  China  is  BeiJing
Capital of  France  is  Paris
Capital of United States is not present.
Entry for France is deleted.
Capital of  Italy  is  Rome
Capital of  Japan  is  Tokyo
Capital of  India  is  New Delhi
Capital of  China  is  BeiJing

13.递归函数

func recursion() {
   recursion() /* 函数调用自身 */
}

func main() {
   recursion()
}

Go 语言支持递归。但我们在使用递归时,开发者需要设置退出条件,否则递归将陷入无限循环中。

递归函数对于解决数学上的问题是非常有用的,就像计算阶乘,生成斐波那契数列等.
阶乘与斐波那契数列:

package main
import "fmt"

func Factorial(n uint64)(result uint64){
    if( n > 0){
        result = n * Factorial( n-1 )
        return result
    }
    return 1
}

func fibonacci(n int) int {
    if n < 2 {
        return n
    }
    return fibonacci(n-2) + fibonacci( n -1)
}

func main(){
    //factorial
    var i int = 15
    fmt.Printf("%d 的阶乘是 %d\n", i, Factorial(uint64(i)))

    //fibonacci
    var j int
    for j = 0; j < 10; j++{
        fmt.Printf("%d\t",fibonacci(j))
    }
}

结果:

15 的阶乘是 1307674368000
0   1   1   2   3   5   8   13  21  34  

14.类型转换

格式:

type_name(expression)

example:

package main
import "fmt"

func main() {
   var sum int = 17
   var count int = 5
   var mean float32
   
   mean = float32(sum)/float32(count)
   fmt.Printf("mean 的值为: %f\n",mean)
}

结果:

mean 的值为: 3.400000

15.interface 接口

Go 语言提供了另外一种数据类型即接口,它把所有的具有共性的方法定义在一起,任何其他类型只要实现了这些方法就是实现了这个接口。

/* 定义接口 */
type interface_name interface {
   method_name1 [return_type]
   method_name2 [return_type]
   method_name3 [return_type]
   ...
   method_namen [return_type]
}

/* 定义结构体 */
type struct_name struct {
   /* variables */
}

/* 实现接口方法 */
func (struct_name_variable struct_name) method_name1() [return_type] {
   /* 方法实现 */
}
...
func (struct_name_variable struct_name) method_namen() [return_type] {
   /* 方法实现*/
}

实例:

package main
import "fmt"

type Phone interface{
    call()
}

type NokiaPhone struct{

}

func (nokiaPhone NokiaPhone) call(){
    fmt.Println("I am Nokia,I can call you!")
}

type IPhone struct{

}

func (iphone IPhone) call(){
    fmt.Println("I am iPhone,I can call you")
}

func main(){
    var phone Phone

    phone = new(NokiaPhone)
    phone.call()

    phone = new(IPhone)
    phone.call()
}

运行结果:

I am Nokia,I can call you!
I am iPhone,I can call you

上面定义了一个接口Phone,接口里面有方法call()。然后在main函数里面定义了一个Phone类型变量,并分别为他们赋值为NokiaPhone和IPhone。然后调用call方法。这个和c++有些不一样,虽然也是new,但是不一样的。
16.错误处理


自带的error类型接口:

type error interface {
    Error() string
}

例子:

func Sqrt(f float64) (float64, error) {
    if f < 0 {
        return 0, errors.New("math: square root of negative number")
    }
    // 实现
}
......
result, err:= Sqrt(-1)

if err != nil {
   fmt.Println(err)
}

实例2:

package main
import "fmt"

//定义一个DivideError 结构
type DivideError struct{
    dividee int
    divider int
}

//实现 'error' 方法
func (de *DivideError) Error() string{
    strFormat :=`Cannot proceed,the divider is zero.
    dividee: %d
    divider: 0`

    return fmt.Sprintf(strFormat,de.dividee)
}

//定义 'int' 类型出发运算的函数
func Divide(varDividee int,varDivider int) (result int,errorMsg string){
    if varDivider == 0{
        dData := DivideError{
            dividee: varDividee,
            divider: varDivider,
        }
        errorMsg = dData.Error()
        return
    }else{
        return varDividee / varDivider,""
    }
}

func main(){
    //正常情况
    if result, errorMsg := Divide(100,10); errorMsg ==""{
        fmt.Println("100/10 = ",result)
    }
    // 当被除数为零的时候会返回错误信息
    if _,errorMsg := Divide(100,0);errorMsg != ""{
        fmt.Println("errorMsg is :",errorMsg)
    }
}

结果:

100/10 =  10
errorMsg is : Cannot proceed,the divider is zero.
    dividee: 100
    divider: 0

习惯c++和python的语法要转化一下思维~~~~

注,语法是根据
http://www.runoob.com/go/go-ide.html
来的。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,732评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,496评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,264评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,807评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,806评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,675评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,029评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,683评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,704评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,666评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,773评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,413评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,016评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,204评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,083评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,503评论 2 343

推荐阅读更多精彩内容