基础-1

  1. 主函数:程序有且只有一个主函数
    package main  //导入主函数的包
    func main() {
    }
    
  2. 打印的模块:fmt
    package main
    import "fmt"
    func main() {
        fmt.Println("Hello", "World")  // Hello World
    }
    

变量

  1. 内存是一个连续的数据集合,每一块内存都有唯一的地址编号,称为内存地址;
  2. 内存地址编号是由一个无符号十六进制整型数据表示的;
  3. 变量名其实就是为内存地址所起的别名;
  4. 变量的声明:var 变量名 数据类型
    var a int  //声明
    a = 10  //赋值
    
  5. 变量的定义:var 变量名 数据类型 = 值
    var a int = 10
    
  6. 自动类型推导:变量名 := 值
    num := 10  //推导num的类型为整型
    
  7. 多重赋值:变量1, 变量2, 变量3 := 值1, 值2, 值3
    a, b, c, d := 1, 2, 3, 4
    
  8. 交换两个变量的值
    a, b := 1, 2
    a, b = b, a
    
  9. 匿名变量
    _, b, _, d := 1, 2, 3, 4
    fmt.Println(b, d) // 2  4
    fmt.Println(_)  //编译报错
    

格式输出

fmt.Println()、fmt.Print()、fmt.Printf():换行输出、不换行输出、格式化输出;

  1. 整型:%d
        a := 10
        fmt.Printf("%d", a)  // 10
    
    1. 指定占的位数:默认使用空格占位,正数表示左侧占位,负数表示右侧占位
        fmt.Printf("==%4d==", a)  // ==  10==
        fmt.Printf("==%-4d==", a) // ==10  ==
        fmt.Printf("==%04d==", a) // ==0010==
    
    1. 位数小于原数值,则原样输出;
        a := 123456
        fmt.Printf("%3d", a)  // 123456
    
  2. 浮点型:%f,默认保留 6 为小数,如果第 7 位大于 5,则进 1
        a := 3.1415926
        fmt.Printf("%f", a)  // 3.141593
    
    1. 指定小数位数时,四舍五入
        fmt.Printf("%.3f", a)  // 3.142
    
  3. \n:转义字符,换行符
  4. 布尔型 %t,字符串 %s,字符型 %c
    var c byte = 'a'
    fmt.Println(c)  // 56,'a'对应的ASCII码值
    fmt.Printf("%c", c)  // a
    
  5. %p:输出一个数据对应的内存地址(十六进制),& 是取地址运算符
    var a int
    fmt.Printf("%p", &a)  // 0xc000056080
    
  6. %%:输出一个 %
  7. %b:把数值转为二进制输出,Go中没有表示二进制数据的方式!
    a := 159  //十进制数值
    fmt.Printf("%b", a)  // 10011111
    
  8. %o:一个八进制表示的数值,以 0 开头,每个值的范围是 0-7
    a := 100  //十进制数值
    fmt.Printf("%o", a)  // 144
    b := 0123  //八进制数值,
    fmt.Printf("%o", b)  // 123
    
  9. %x、%X:十六进制表示的数值(0x开头),区别是大小写字母a-fA-F
  10. %T:输出一个值的类型;
  11. %s 与 %q:都是用于打印字符串,不同的是,后者会带上Go语言格式;
    str := "hello"
    fmt.Printf("%q", str)  // 打印的是:"hello"
    fmt.Printf("%s", str)  // 打印的是:hello
    

格式输入

  1. fmt.Scan():取出键盘输入的数据;
    var a int
    fmt.Scan(&a)  // 从 a 的内存地址中取出键盘输入的数据,123.456
    fmt.Println(a)  //123,a是整型数据,所以小数部分会被舍弃
    
    var a string
    fmt.Scan(&a)  // helloworld
    fmt.Println(a)  // helloworld
    
  2. 遇到空格键,表示一次接收结束,但可以使用多个变量接收键盘输入;
    var a string
    fmt.Scan(&a)  // hello world
    fmt.Println(a)  // hello
    
    var a,b string
    fmt.Scan(&a, &b)  // hello world
    fmt.Println(a, b)  // hello world
    
  3. fmt.Scanf():格式化接收键盘输入的数据;
    var a int
    var b string
    fmt.Scanf("%d%s", &a, &b)  // 123world456
    fmt.Println(a, b)  // 123 world456 整数部分给了a,剩下的给了b
    
    var a int
    var b string
    fmt.Scanf("%3d%s", &a, &b)  // 123456world
    fmt.Println(a, b)  // 123 456world 规定a只接收3个整数,剩下的给b
    

基本数据类型

  1. bool:布尔型,长度为1,默认值false
  2. byte:字节型,长度为1,默认值0,其实是 uint8 的别名
    c := 'x'
    fmt.Printf("%T", c)  // int32
    var c1 byte = 'x'
    fmt.Printf("%T", c1)  // uint8
    
  3. 整型:默认值0
    1. int、uint:有符号32位或无符号64
    2. int8、uint8:长度为1,取值范围-128 ~ 1270 ~ 255
    3. int16、uint16:长度为2,取值范围-32768 ~ 327670 ~ 65535
    4. int32、uint32:长度为4
    5. int64、uint64:长度为8
        num := 12
        fmt.Printf("%T", num)  // int
        c := 'x'
        fmt.Printf("%T", c)  // int32
        var c1 byte = 'x'
        fmt.Printf("%T", c1)  // uint8
    
    1. 一个 int 类型会根据操作系统的不同,占用 48 个字节,64x系统占用8字节.
  4. 浮点型:默认值0.000000
    1. float32:长度为4,,小数位精确到7位;
    2. float64:长度为8,小数位精确到15位;
        f := 3.14
        fmt.Printf("%T", f)  // float64
    
  5. string:字符串,utf-8字符串,默认值是空字符串
    1. 空字符串实际是一个空字符:\0
    2. 一个字符串的结束就是以 \0 为标识,但它对开发者是不可见的!

keep moving

  1. 在Go中,一个汉字等于3个字符,为了和Linux同一处理;
        var a string = "go语言"
        num := len(str)  //计算字符串的个数
        fmt.Println(num)  // 8
    
  2. 常量:const,一旦定义,则不允许修改;
        const A int = 10
        const PI = 3.14
    
    1. 内存可以简单划分为代码区、数据区、栈区、堆区
    2. 普通的变量一般存放在栈区,常量则存放在数据区
    3. 系统为每一个应用程序分配 1M 的栈区空间存放变量,程序运行结束后,系统自动清空栈区;
    4. 常量不能使用 & 取地址;
  3. iota枚举:常量生成器,用于生成一组以相似规则初始化的常量;
        const (
            a = iota  //0
            b = iota  //1
            c = iota  //2
        )
        fmt.Println(a, b, c)  // 0 1 2
        //通过修改value的值,控制不同的状态
        value := a
        value := b
        value := c
    
    1. 默认情况下,第一个iota的值是0,后面的值自动累加1
    2. 简写形式
        const (
            a = iota  //0
            b
            c
        )
        fmt.Println(a, b, c)  // 0 1 2
    
    1. 写在同一行的iota,其值相同
        const (
            a = iota  //0
            b,c = iota, iota
            d, e
        )
        fmt.Println(a, b, c, d, e)  // 0 1 1 2 2
    
    1. 可以手动赋初始值,但后面的iota仍保持默认的自增长方式;
        const (
            a = 22  //0
            b,c = iota, iota
            d, e
        )
        fmt.Println(a, b, c, d, e)  // 22 1 1 2 2
    
  4. 算术和赋值运算符:+、-、*、/、%、++、--、=、+=、*=、/=、%=
  5. 不同类型之间不能直接进行计算,需要进行类型转换;
        a := 10
        b := 3.14
        c := float64(a) * b
        d := a * int(b)
    
    1. 浮点型转整型:保留整数部分,舍弃小数部分,不会四舍五入;
    2. 整型之间如果类型不同,也不能直接进行计算,而且通常都会把低类型转为高类型,尽量避免数据溢出!
        var a int32 = 10
        var b int64 = 20
        c := int64(a) + b
    
  6. 关系和逻辑运算符:结果总是布尔类型,==、!=、<、>、<=、>=、!、&&、||,逻辑与&&的优先级高于逻辑或||
  7. &:取内存地址运算符,如&b 表示获取变量b 的内存地址;
  8. *:取值运算符,如*b 表示指针变量b 所指向内存的值;
    b := 10
    p := &b
    fmt.Println(p)  // 10
    

控制语句

  1. if
    score := 70
    if score>100 {
    } else if score>80 {
    } else {
    }
    
  2. switch
        score := 70
        switch score {
            case 100:
                fmt.Println(score)
            case 60:
                fmt.Println(score)
            default:
                fmt.Println(score)
        }
    
    1. 不支持浮点型数据,因为浮点数是一个约等于的数值;
    2. 支持布尔型,但表达式只能是单一区间
        score := 70
        switch score>60 {
            case true:
                fmt.Println(score)
            case false:
                fmt.Println(score)
        }
    
    1. 支持表达式,支持 case 的合并
        score := 70
        switch score/10 {
            case 1:
                fallthrough  //执行下一个case
            case 2:
                fmt.Println(score)
            case 3:
                fmt.Println(score)
            default:
                fmt.Println(score)
        }
    
  3. for 循环
        for 表达式1; 表达式2; 表达式3 {
            循环体
        }
        ```
        ```go
        for i:=1; i<10; i++ {
            fmt.Println(i)
        }
    
    1. 三个表达式都可以省略
        i:=1
        for ; i<10; i++ {
            fmt.Println(i)
        }
        for ;; i++ {
            if i>10 {
                break
            }
            fmt.Println(i)
        }
        for ;; {
            if i>10 {
                break
            }
            fmt.Println(i)
            i++
        }
    
    1. break 只能跳出本次循环,对于循环嵌套的时候需要注意!
    2. continue 继续下次循环,下面的代码不再执行!
    3. 空死循环
        for {
            ;
        }
    

函数

  1. 定义
    func 函数名(参数列表) {
        函数体
    }
    
    func sum(a int, b int, c int) {
        s := a+b+c
        fmt.Println(s)
    }
    func main() {
        sum(1,2,3)  // 6
    }
    
    1. 如果多个连续的形参类型相同,可以省略前面形参的类型
    func sum(a, b, c int) {
    }
    
  2. 函数本身存储在代码区,函数的调用存储在栈区;
  3. 不定长参数:...数据类型,被封装在一个slice(切片)中,len(args)可以计算切片的长度;
        func sum(a int, args ...int) {
            fmt.Println(args)
        }
        sum(1,2,3)  // [2 3]
        sum(1,2,3,4,5)  // [2 3 4 5]
    
  4. 所有的函数都是全局函数,可以被项目中的其他文件调用,所以项目中的函数名是唯一的;
  5. 返回值
        func 函数名(参数列表) 返回值类型列表 {
            函数体
            return 返回值
        }
    
        func sum(a int, b int, c int) int {
            s := a+b+c
            return s
        }
        func main() {
            value := sum(1,2,3)
        }
    
    1. 预声明返回值变量
        func sum(a int, b int, c int) (count int) {
            count = a+b+c
            return
        }
        func main() {
            value := sum(1,2,3)
        }
    
    1. Go支持多个返回值
        func sum() (a int, b bool, c string) {
            a,b,c = 1,true,"hello"
            return
        }
        a,b,c := sum()  //接收三个返回值 1,true,"hello"
        a,_,c := sum()  //选择接收两个返回值 1,"hello"
    
  6. 函数类型
        func sum(a int, b int, c int) {
            s := a+b+c
            fmt.Println(s)
        }
        fmt.Printf("%T", sum)  // func(int, int, int)
    
    1. 为函数起别名
        f := sum
        f(1, 2, 3)  // 6
        fmt.Printf("%T", f)  // func(int, int, int)
    
        var f func(int, int, int) = sum  // var f = sum
        f(1, 2, 3)  // 6
        fmt.Printf("%T", f)   // func(int, int, int)
    
    1. type:可以定义函数类型/格式,还可以为已存在的类型起别名;
        func test1() {
            fmt.Println("test1")
        }
        type FUNCTEST func()  //定义函数类型 FUNCTEST
        func main() {
            var f FUNCTEST
            f = test1
            f()  // test1
        }
    
        func test2(x int, y int) {
            fmt.Println(x, y)
        }
        type FUNCDEMO func(int, int)  //定义函数类型 FUNCDEMO
        func main() {
            var f FUNCDEMO
            f = test2
            f(1, 2)  // 1 2
        }
    
        func test3(x int, y int) int {
            return x+y
        }
        type FUNCEXAM func(int, int)int  //定义函数类型 FUNCEXAM
        func main() {
            var f FUNCEXAM = test3
            f(1, 2)  // 3
        }
    
    1. 函数名本身就是一个指针类型的数据,指向函数体所在的内存地址
        fmt.Println(f)  // 0x491080
        fmt.Println(test3)  // 0x491080
    
  7. 作用域
    1. 函数内定义的变量都是局部变量,函数外部定义的变量是全局变量,且全局变量不能使用自动类型推导;
    2. 全局变量可以被项目中的所有文件引用;
    3. 局部变量存储在栈区,全局变量和常量都存在数据区;
    4. & 可以取全局变量的地址,但不能取常量的地址;
  8. 匿名函数与闭包
    1. Go支持在函数中继续定义函数,它是一个匿名函数;
        func main() {
            // 匿名自执行函数
            func() {
                fmt.Println(2)
            }()  // 2
    
            //给匿名函数起别名
            fx := func(x int, y int) {
                fmt.Println(x, y)
            }
            fx(1, 2)  // 1 2
    
            //带返回值的匿名自执行函数
            fy := func(x int, y int)int {
                return x+y
            }(1, 2)  // 3
        }
    
    1. 闭包:函数返回值是一个匿名函数
        func wrap() func() int {
            var a int
            return func() int {
                a++   //内部函数持有外部函数的变量
                return a
            }
        }
        func main() {
            f := wrap()
            f()  // 1
            f()  // 2
            f()  // 3
        }
    
    1. 通过匿名函数和闭包,实现函数在栈区的本地化.

工程管理

  1. Go项目目录
    1. src:源代码,.go、.c、.h、.s等文件;
    2. pkg:由 go install 命令构建安装的代码包,包含Go库源码文件, .a 归档文件;
    3. bin:与 pkg 目录类似,通过 go install 命令完成安装后,保存由Go命令生成的可执行文件。
  2. 创建 src 目录,配置编译项为Directory,并选择src目录路径;
  3. 同级别目录
    1. 源文件的包名必须是相同的,且主函数main()的包名总是package main
    2. 源文件中的全局变量和函数是共享的,可以相互调用。
  4. 不同级别的目录
    1. 调用其他目录下的函数和变量时,需要导入其包名,且函数和变量的命名必须以大写字母开头!
    2. 小写字母开头的函数和变量是私有的,不允许其他目录中的文件调用!
  5. 在一个项目中,包名是唯一的!

复合类型

复合类型主要包括:数组、指针、切片、结构体...

数组

  1. 定义:var 变量名 [容量]数据类型
    1. 声明一个元素个数为10、元素类型为int 的数组
        var arr [10]int
    
    1. 定义数组并初始化
        var arr [5]int = [5]int{1,2,3,4,5}
        fmt.Println(arr[2])  // 3
    
    1. 定义数组并初始化部分元素
        arr := [5]int{1,2,3}
        fmt.Println(arr[4])  // 0
    
    1. 定义数组时,指定初始化哪些元素
        arr := [10]int{1,2,3, 7:10}  //索引为7 的元素为10
        fmt.Println(arr[7])  // 10
    
    1. 使用类型推导,可以根据元素个数创建数组
        arr := [...]int{1,2,3,4,5,6}
    
  2. 数组的容量一旦声明,就不可更改,使用 len() 可以获取数据长度;
  3. range:遍历集合信息
        arr := [...]int{1,2,3,4,5}
        for i,v:=range arr {
            fmt.Println(i, v)
        }
    
    1. i 表示数组的角标,v表示数组元素
  4. 数组是一块连续的存储空间,数组名指向首地址;
    arr := [...]int{1,2,3,4,5}
    fmt.Printf("%p", &arr)     // 0xc00006c060
    fmt.Printf("%p", &arr[0])  // 0xc00006c060
    fmt.Printf("%p", &arr[2])  // 0xc00006c070
    
  5. 在Go中,数组作为参数的传递也是值传递!
        func test(arr [5]int) {
            arr[2] = 100  //修改数组元素的值
            fmt.Printf("%p", &arr)  // 0xc00005c0a0
        }
        func main() {
            arr := [5]int{1,2,3,4,5}
            fmt.Printf("%p", &arr)  // 0xc00005c050
            test(arr)
    
            b := arr
            b[2] = 200
    
            fmt.Printf("%p", &b)  // 0xc00006c060
            fmt.Println(b)  // b:[1 2 200 4 5]
    
            fmt.Println(arr)  // arr:[1 2 3 4 5]
        }
    
    1. 对于值传递,如果数组中的元素支持==、!=,那么该数组也支持==、!=
        arr := [5]int{1,2,3,4,5}
        b := [5]int{1,2,3,4,5}
        fmt.Println(b == arr)  // true
    
    1. 把数组作为返回值,返回一个新的数组
        func test(arr [10]int) [10]int {
            arr[2] = 100  //修改数组元素的值
            return arr
        }
        func main() {
            arr := [10]int{1,2,3,4,5}
            arr = test(arr)
        }
    
  6. 随机数:导入 math/rand
    1. 时间包:time
        time.Now()  // 当前时间 2019-09-05 18:24:53.5059375 +0800 CST m=+0.002991601
        time.Now().Unix() // 当前时间的毫秒值 1567679093
        time.Now().UnixNano() // 当前时间的纳秒值 1567679093519899400
        time.Now().UnixNano() // 当前时间的纳秒值 1567679093519899400
        //当前时间
        time.Now().YearDay() // 今天是今年第几天
        time.Now().Year()、Month()、Day()、Date()  //年月日、日期
        time.Now().Hour()、Minute()、Second()、Nanosecond()  //时分秒、纳秒
    
    1. 默认情况下,随机数是根据一个固定时间1970.1.1 0:0:0计算出来的,所以每次生成的随机数都一样;
    2. 加入当前时间作为种子,进行混淆,从而生成随机数!
        rand.Send(time.Now().UnixNano())
        r := rand.Intn(100)  //生成 [0, 100) 的随机数
    
  7. 二维数组
    1. 定义:var 数组名 [行个数][列个数] 数组类型
        var arr[3][4]int
        arr[1][2] = 11
        arr[2][1] = 33
    
        var arr = [3][4]int{{1,2,3,4}, {2,3,4,5}, {3,4,5,6}}
        fmt.Println(arr[2][3]) // 6
    
    1. len() 获取行和列
        var arr[3][4]int
        fmt.Println(len(arr))  // 3
        fmt.Println(len(arr[1]))  // 4
    

切片

与数组相比,切片的长度是不固定的,可以追加元素,虽然它看起来像"动态数组",但它并不是数组!

  1. 定义:var 切片名 []数据类型
    var s [] int
    fmt.Println(s)  // []
    var s2 []int = []int{1, 2, 3, 4, 5}
    fmt.Println(s2)  // [1 2 3 4 5]
    
  2. make([]数据类型, 初始长度) 自动类型推导创建切片
    s := make([]int, 5)
    s[0] = 1
    fmt.Println(s)  // [1 0 0 0 0]
    
  3. 通过索引的方式操作切片时,也不允许超过切片长度;
    s := make([]int, 5)
    s[5] = 1  //error: index out of range
    fmt.Println(100)  //error: index out of range
    
  4. append(切片, 元素1, 元素2, ...):向切片中添加元素,并返回一个新的切片,但不会影响原切片!
    s := make([]int, 5)
    b := append(s, 11, 12)
    fmt.Println(s)  // [0 0 0 0 0]
    fmt.Println(b)  // [0 0 0 0 0 11 12]
    
  5. len() 获取切片的长度,cap() 获取切片的总容量;
    1. append() 在向切片中添加元素时,切片的长度会自动扩展;
    2. 当切片数据小于1024字节时,每次为切片扩展上一次的倍数;超过1024字节时,每次扩展上一次的1/4
        s := make([]int, 5)
        s = append(s, 10, 11)
        len(s)  // 7
        cap(s)  // 10
    
  6. 遍历切片:for i,v:=range slice { }for i:=0; i<len(slice); i++ { }
  7. 截取:slice[起始下标:结束下标:容量]
    1. 省略起始下标,默认从0开始;省略结束下标,默认为len(slice)-1
    2. 截取之后返回一个新的切片,指定的容量不能大于原切片的容量,但不能小于新切片的元素个数!
    3. 新切片只是引用原切片的一部分,使用的是同一块内存地址,所以通过索引修改值时,它们会同步修改!
        src := []int{1, 2, 3, 4, 5, 6}
        dst := src[0:2]  // [1 2]
        src[0] = 2001
        fmt.Println(dst)  // [2001 2]
        fmt.Printf("%p\n", src)  // 0xc0000160f0 切片名就是地址,无需使用 &
        fmt.Printf("%p\n", dst)  //0xc0000160f0
    
  8. 数组存储在栈区,而切片存储在堆区
    1. 堆区的容量远远大于其他内存区域,切片的容量是不固定的,如果储存在栈区,会受容量限制!
    2. 在切片扩展过程中,地址会发生变化,因为切片也是存储在一块连续的内存空间,如果空间不够,系统会重新为其分配内存;
  9. copy(切片1, 切片2):拷贝切片2到切片1中,切片1一定要有足够的容量;
        src := []int{1, 2, 3}
        dst := make([]int, 5)
        copy(dst, src)
        fmt.Println(dst)   // 1 2 3 0 0
    
    1. 不管目标切片中是否有元素,拷贝总是从索引0 开始,如果目标切片中已经有了元素,则被覆盖!
    2. 源切片和目标切片处在不同的内存空间,互不影响!
  10. 切片是引用传递,不支持==、!=
    1. 切片作为实参时,如果函数内对切片使用了 append(),且导致切片扩容,那么形参指向的切片地址会发生变化,最终与原切片脱离关系;
    2. 对于这种情况,应该把修改后的且作为返回值,重新赋给原切片;
        func test(s []int) []int {
            s = append(s, 10, 11, 12)
            return s
        }
        func main() {
            src := []int{1, 2, 3}
            src = test(src)
        }
    

Map

Mapkey-value结构,其中 key 是唯一的,且必须是支持 ==、!= 特性的数据类型,如整型、字符串;

  1. 定义
    1. 声明一个Map,默认值为 nil,并不能直接使用;
        var m map[int] string  //声明 key为int型,value为string型
        m[1] = "Machel"  // 报错:nil map
    
    1. 声明并初始化Map
        m := map[int]string{1:"A", 2:"B", 3:"C"}
    
  2. make() 创建 Map
    m := make(map[int] string, 1)  //key为int型,value为string型,初始容量为1
    m[1] = "Machel"
    m[2] = "Jack"  //自动扩容
    
  3. Map的容量自动扩容,链式存储,无序,所以使用 for k,v:=range map {}遍历
  4. len() 可以计算 Map 的元素个数;
  5. 取值时,可以判断值是否存在
    m := map[int]string{1:"A", 2:"B", 3:"C"}
    v, ok := m[1]
    fmt.Println(v, ok)  // A  true
    
    1. if 语句支持多条语句,以 ; 分割
            if _, ok := m[100]; ok {  // ok 为 true 时,则进入此分支
            }
    
  6. 删除元素:delete(map, key),根据key删除,即使不存在,也不会报错;
  7. Map 是地址(引用)传递。
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,830评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,992评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,875评论 0 331
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,837评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,734评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,091评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,550评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,217评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,368评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,298评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,350评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,027评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,623评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,706评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,940评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,349评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,936评论 2 341

推荐阅读更多精彩内容

  • SwiftDay011.MySwiftimport UIKitprintln("Hello Swift!")var...
    smile丽语阅读 3,824评论 0 6
  • 数组 和C语言一样,Go语言中也有数组的概念, Go语言中的数组也是用于保存一组相同类型的数据 和C语言一样,Go...
    极客江南阅读 1,199评论 0 2
  • 使用定时器t := time.NewTicker(1 * time.Second)// 第一种方式for { ...
    qishuai阅读 909评论 0 2
  • fmt格式化字符串 格式:%[旗标][宽度][.精度][arg索引]动词旗标有以下几种:+: 对于数值类型总是输出...
    皮皮v阅读 1,085评论 0 3
  • 在C语言中,五种基本数据类型存储空间长度的排列顺序是: A)char B)char=int<=float C)ch...
    夏天再来阅读 3,307评论 0 2