GO.5——字符串,,指针,,结构体,,方法

字符串

# Go 语言中的字符串是一个字节(byte)切片 []byte 。把内容放在双引号””之间,我们可以创建一个字符串。让我们来看一个创建并打印字符串的简单示例

package main

import (
    "fmt"
    "unicode/utf8"
)

// 字符串
func main() {
    // 1 介绍
    var s string = "lqz-中国"
    fmt.Println(s[0])            // 按下标取值---》但是不能改
    fmt.Printf("类型是:%T\n", s[0]) // 按下标取值---》取到字节---》但是不能改

    //2 不可变: 如果要改字符串---》转成字节数组(字节切片)---》修改完---》转成字符串

    // 3 循环字节
    for i := 0; i < len(s); i++ {
        fmt.Println(string(s[i]))
    }

    //4  循环字符
    for _, value := range s {
        fmt.Println(string(value))

    }

    // 5 字符串长度:字节长度
    fmt.Println(len(s))
    //6  字符串长度:字符长度
    fmt.Println(utf8.RuneCountInString(s))

    //7 字节切片构造字符串
    var b []byte = []byte{'a', 'b', 98}
    fmt.Println(string(b))
    //8 字符切片构造字符串
    var r []rune = []rune{20013, '', 98}
    fmt.Println(string(r))

}

指针

指针是一种存储变量内存地址(Memory Address)的变量

 

package main

import "fmt"

// 指针
// 1    & (取地址符号)放在变量前,表示取这个变量的地址

// 2   *   放在类型前,表示指向这个类型的指针---》定义类型

// 3   * 放在变量前(指针类型变量),解引用--》把指针指向的值,解出来
func main() {

    //1 指针基本使用---三句话
    //var a int = 10
    //
    ////var p = &a
    //var p *int = &a
    //fmt.Println(p) // 0xc00000a0c8
    //
    //var s = "lqz"
    //var p1 *string = &s
    //fmt.Println(p1)
    //
    //var arr = [3]int{5, 6, 7}
    //var p2 *[3]int = &arr
    //fmt.Println(p2) //内存地址---》显示成 &[5 6 7]
    //
    //// p 真正的指向了谁
    //
    //fmt.Println(*p)
    //fmt.Println(*p1)
    //fmt.Println(*p2)

    // 2 指针的指针

    //var a int = 10
    //
    //var p1 *int = &a
    //
    //var p2 **int = &p1
    //
    //var p3 ***int = &p2
    //
    //fmt.Println(p3)
    //fmt.Println(p2)
    //fmt.Println(p1)
    //fmt.Println(*p3) // p2的值
    //fmt.Println(*p2) // p1的值
    //fmt.Println(*p1) // a的值 10
    //
    //fmt.Println(***p3) // a的值 10
    //

    // 3 指针零值---》引用---》如果不赋初值--》就是空指针---><nil>
    // 所有引用类型的空值 :nil
    // 所有值类型的零值:都是默认值 数字就是0,字符串就是 ""   布尔就是false

    //var p1 *int
    //fmt.Println(p1)

    // 4 向函数传递指针参数
    //var a = 100
    //test001(&a)
    //fmt.Println("外层", a) // a是多少?101

    // 5 不要向函数传递数组的指针,而应该使用切片

    //var arr = [3]int{9, 8, 7}
    //test002(&arr)
    //fmt.Println("外层", arr)
    //
    //var arr1 = [400]int{9, 8, 7}
    //test003(arr1[:])
    //fmt.Println("外层-层", arr1)

    // 6 指针不允许运算-->c语言中指针能运算

    // 7 指针数组【数组中放的是指针类型】和数组指针【指向数组的指针】

    var arr = [3]int{9, 8, 7}
    var p1 *[3]int = &arr // 数组指针【指向数组的指针】
    fmt.Println(p1)       // &[9,8,7]

    var a, b, c = 99, 88, 77 // 指针数组
    var p2 [3]*int = [3]*int{&a, &b, &c}
    fmt.Println(p2) // [0x111,0x3212,0xasfasd]

}

func test001(p *int) {
    fmt.Println(p)  //内存地址
    fmt.Println(*p) // 内存指向的值  100
    (*p)++          // 对100 +1   101
    fmt.Println(*p) // 101
}
func test002(p *[3]int) {
    (*p)[0] = 999 // *p 解引用,解成数组---》取第0个位置,改成 999
    fmt.Println(*p)
}

func test003(p []int) {
    p[0] = 888 // 通过切片改值
    fmt.Println(p)
}

结构体

# 什么是结构体?
结构体是用户定义的类型,表示若干个字段(Field)的集合。有时应该把数据整合在一起,而不是让这些数据没有联系。这种情况下可以使用结构体。

例如,人有姓名,性别,年龄---》三个字段,放到一个结构体中,而不是把它定义成三个变量

# 结构体:就是面向对象中类的概念---》只有属性,没有方法

package main

import (
    "fmt"
    "go_day05/entity"
)

// 结构体--》用户定义的类型

// 1 ########定义结构体########
// 定义一个人结构体,有三个字段
//type Person struct {
//    name   string
//    age    uint
//    gender string
//}

// 定义狗结构体---》匿名字段--》字段没有名字
//type Dog struct {
//    string // 狗名字,不写
//    uint
//    age uint // 如果有两个类型一致,不能使用匿名字段
//}

// 10 结构体嵌套 结构体中套结构体
//type Cat struct {
//    name string
//    age  uint
//    // 爱好,结构体类型--》Hobby
//    hobby Hobby
//}
//type Hobby struct {
//    id   int
//    name string
//}

// 12 结构体嵌套+匿名字段
//type Cat struct {
//    name  string
//    age   uint
//    Hobby // 匿名字段
//}
//type Hobby struct {
//    id   int
//    name string
//}

func main() {
    // 1 定义结构体

    // 2 使用结构体--》定义一个Person类型变量---》操作
    //var person Person   // 定义,没有赋初值
    //fmt.Println(person) // 如果是nil,表示它是引用类型,如果有默认值,他就是值类型---》值类型

    // 3 修改和获取结构体的元素
    //person.name = "彭于晏"
    //person.age = 10
    //person.gender = "女"
    //fmt.Println(person)

    // 4 打印人名
    //fmt.Println(person.name)

    // 5 定义并初始化
    //var person1 Person = Person{"刘亦菲", 88, "女"} // 按位置,不能少
    //var person2 = Person{name: "迪丽热巴"}          // 按关键字,少传--》没传的默认零值
    //fmt.Println(person1.name)
    //person2.gender = "男"
    //fmt.Println(person2.gender) // ""

    // 6 结构体是值类型---》不初始化,也能使用---》当参数传递,再函数中修改了,会影响原来的吗? 不会
    //var person1 Person = Person{"刘亦菲", 88, "女"}
    //test004(person1)
    //fmt.Println("外部:", person1)

    // 7 如果想改原来的值--取地址
    //var person1 *Person = &Person{"刘亦菲", 88, "女"}
    //test005(person1)

    //var person1 Person = Person{"刘亦菲", 88, "女"}
    //test005(&person1)
    //fmt.Println("外部:", person1)

    // 8 匿名字段 --》结构体是一系列字段的集合---》字段可以没有名字
    // 初始化狗结构体
    //var dog Dog = Dog{"小奶狗", 30, 2} // 按位置赋值
    //var dog Dog = Dog{string: "小奶狗", uint: 30, age: 2} // 按关键字赋值  -->如果是匿名字段--》类型名就是字段名
    //fmt.Println(dog)

    // 9 获取和修改匿名字段的值---》按类型名获取即可
    //dog.string = "小奶奶狗"
    //fmt.Println(dog.string)

    // 10 结构体嵌套

    // 11 结构体嵌套 初始化
    //var cat Cat
    //var cat Cat=Cat{"小野猫",4,Hobby{1,"篮球"}}
    //var cat Cat=Cat{name:"小野猫",age:4,hobby: Hobby{1,"篮球"}}  //关键字
    //var cat Cat = Cat{name: "小野猫", age: 4, hobby: Hobby{id: 1, name: "篮球"}} //关键字
    //fmt.Println(cat)
    ////拿到猫的爱好id
    //fmt.Println(cat.hobby.name)

    // 12 结构体嵌套+匿名字段---》字段提升
    //var cat Cat = Cat{"小野猫", 4, Hobby{1, "篮球"}}
    ////var cat Cat = Cat{name: "小野猫", age: 4, Hobby: Hobby{id: 1, name: "篮球"}}
    //fmt.Println(cat.Hobby.name)
    //fmt.Println(cat.id) // cat 没有id--》因为Hobby是匿名字段--》把内部的字段提升到外层
    //// cat 有name,hobby也有name ,字段会提升吗?  不会提升
    //fmt.Println(cat.name)

    // 有什么用?字段提升---》面向对象的继承---》Cat继承了Hobby---》cat.id-->自己没有--》直接拿到父类的属性

    // 13 导出结构体字段---》使用entity包下的dog---》面向对象封装
    // 无论是结构体还是字段,想在别的包使用,必须大写开头
    var dog entity.Dog = entity.Dog{Name: "野狗"}
    fmt.Println(dog.Name)

}

//func test004(person Person) {
//    person.name = "xxxxx"
//    fmt.Println(person)
//
//}
//
//func test005(person *Person) {
//    (*person).name = "xxxxx"
//    fmt.Println(*person)
//
//}

方法

# 方法其实就是一个函数,在 func 这个关键字和方法名中间加入了一个特殊的接收器类型。接收器可以是结构体类型或者是非结构体类型。接收器是可以在方法的内部访问的


# 函数  方法
    方法-->特殊--》自动传值--》绑定给对象或类的
    
    
package main

import "fmt"

// 方法

type Fish struct {
    name string
    age  uint
}

// 结构体绑定方法

func (fish Fish) getName() string {
    return fish.name
}

func main() {

    var fish Fish = Fish{"小金鱼", 1}
    res := fish.getName() // 自动传值
    fmt.Println(res)

}

 

posted @ 2024-04-09 09:57  拆尼斯、帕丁顿  阅读(40)  评论(0)    收藏  举报