字符串
字符串的定义
package main
import "fmt"
func main() {
//hello world
var str string = "hello world"
fmt.Println(str)
}
字符串的操作
package main
import (
"fmt"
"strconv"
"strings"
)
func main() {
//hello world
var str string = "hello world"
fmt.Println(str)
// Contains
fmt.Println(strings.Contains(str,"hello"))
// Index
fmt.Println(strings.Index(str,"world"))
// Split
fmt.Println(strings.Split(str,"lo"))
// Format : 将其他类型的数据 转换为字符串
var str2 string= strconv.FormatBool(true)
fmt.Println(str2)
// Itoa 整型转字符串
var str3 string
str3 = strconv.Itoa(666)
fmt.Println(str3)
// Parse 将字符串转换为其他类型
if flag,err := strconv.ParseBool("true");err == nil{
fmt.Println(flag)
}else {
fmt.Println(err)
}
}
Map
什么是Map
GO语言中的Map,也称为字典,是有键和值构成的。
Map的定义
var a map[int]int
定义字典结构使用map关键字,[ ]中指定的是键(key)的类型,后面紧跟着的是值的类型。
键的类型,必须是支持==和!=操作符的类型,切片、函数以及包含切片的结构类型不能作为字典的键,使用这些类型会造成编译错误。
注意:字典中不能使用cap函数,只能使用len( )函数。len( )函数返回map拥有的键值对的数量。
定义一个map:
package main
import "fmt"
func main() {
a:= make(map[string] string)
fmt.Println(a,len(a))
a["test"] = "张三"
a["devops"] = "李四"
fmt.Println(a,len(a))
b:= map[int]string{1:"mark",2:"picaso",3:"joe"}
fmt.Println(b,len(b))
//打印map的值
for k,v := range b {
fmt.Println("key = ",k)
fmt.Println("value = ",v)
}
}
结构体
结构体的定义
type Student struct {
id int
name string
sex byte // 字符类型
age int
address string
}
type 后面跟着的是结构体的名字Student, struct表示定义的是一个结构体。
大括号中是结构体的成员,注意在定义结构体成员时,不要加var.
通过以上的定义,大家能够感觉出,通过结构体来定义复杂的数据结构,非常清晰。
结构体定义完成后,可以进行初始化。
结构体的初始化
package main
import "fmt"
type Student struct {
id int
name string
sex byte // 字符类型
age int
address string
}
func main() {
// 顺序初始化,每个成员必须初始化
mark := Student{1,"mark",'m',25,"长沙"}
fmt.Println(mark)
// 指定成员初始化,没有初始化的成员,自动赋值为0
leo:= Student{name: "leo"}
fmt.Println(leo)
}
输出如下:
{1 mark 109 25 长沙}
{0 leo 0 0 }
比较与赋值
两个结构体可以使用 == 或 != 运算符进行比较,但不支持 > 或 <。
mark := Student{1,"mark",'m',25,"长沙"}
mark2 := Student{1,"mark",'m',25,"长沙"}
fmt.Println(mark == mark2)
输出如下:
true
结构体数组
package main
import "fmt"
type Student struct {
id int
name string
sex byte // 字符类型
age int
address string
}
func main() {
marks:= []Student{{name: "mark",age: 18},{name: "mask",age: 20}}
fmt.Println(marks)
}
输出如下:
[{0 mark 0 18 } {0 mask 0 20 }]
结构体做函数参数
package main
import "fmt"
type Student struct {
id int
name string
sex byte // 字符类型
age int
address string
}
func main() {
marks:= Student{name: "mark",age: 18}
testStruct(marks)
}
func testStruct(student Student) {
fmt.Println(student)
}
结构体作为函数参数进行传递,是值传递!
指针
什么是指针
一个指针变量指向了一个值的内存地址。
类似于变量和常量,在使用指针前你需要声明指针。指针声明格式如下:
var var_name *var-type
var-type 为指针类型,var_name 为指针变量名,* 号用于指定变量是作为一个指针。以下是有效的指针声明:
var ip *int /* 指向整型*/
var fp *float32 /* 指向浮点型 */
指针的定义
package main
import "fmt"
func main() {
a := 100
var p *int
p = &a
fmt.Printf("a的内存地址为:%p ,值为:%d\n", p, *p)
}
输出如下:
a的内存地址为:0xc0000ac058 ,值为:100
指针变量p的定义是通过 *这个符号来定义,指针变量p的类型为*int, 表示存储的是一个整型变量的地址。
如果指针变量p存储的是一个字符串类型变量的地址,那么指针变量p的类型为*string
**p=&a 😗*该行代码的意思是,将变量a的地址取出来,并且赋值给指针变量p.也就是指针变量p指向了变量i的存储单元。
大家可以思考一个问题:
既然指针变量p指向了变量a的存储单元,那么是否可以通过指针变量p,来操作变量i中存储的数据?
答案是可以的,具体操作方式如下: *p = 66
package main
import "fmt"
func main() {
a := 100
var p *int
p = &a
*p = 66
fmt.Printf("a的值为:%d\n", a)
}
输出如下:
a的值为:66
指针作为函数参数
指针也可以作为函数参数,那么指针作为函数参数在进行传递的时候,是值传递还是引用传递呢?
package main
import "fmt"
func main() {
a := 100
var p *int
p = &a
fmt.Printf("a的值为:%d\n", a)
testPoint(p)
fmt.Printf("调用后,a的值为:%d\n", a)
}
func testPoint(p *int) {
*p = 666
}
输出如下:
a的值为:100
调用后,a的值为:666
通过以上案例证实,指针作为参数进行传递时,为引用传递,也就是传递的地址。
数组指针
前面在讲解数组的时候,我们用数组作为函数参数,但是数组作为参数进行传递是值传递,如果想引用传递,可以使用数组指针。具体使用方式如下:
package main
import "fmt"
func main() {
a := [5]int{1, 2, 3, 4, 5}
testPoint(&a)
fmt.Println(a)
}
func testPoint(p *[5]int) {
// *p 的值 等于数组a的值
fmt.Println(*p)
(*p)[0] = 666
}
输出如下:
[1 2 3 4 5]
[666 2 3 4 5]
指针p,指向了数组a,对指针p的操作实际上是对数组a的操作,所以如果直接执行如下语句:fmt.Println(*p),会输出数组a中的值。也可以通过*p结合下标将对应的值取出来进行修改。最终在main函数中输出数组a,发现其元素也已经修改。
指针数组
上一小节,讲解到的是数组指针,也就是让一个指针指向数组 ,然后可以通过该指针来操作数组。还有一个概念叫指针数组,这两个概念很容混淆,指针数组指的是一个数组中存储的都是指针(也就是地址)。也就是一个存储了地址的数组。
下面通过一个案例,看一下指针数组的应用:
package main
import "fmt"
func main() {
var p [2]*int
i, j := 10, 20
p[0], p[1] = &i, &j
fmt.Println(p, *p[0], *p[1])
}
输出如下:
[0xc0000ac058 0xc0000ac070] 10 20
指针数组的定义方式,与数组指针定义方式是不一样的,注意指针数组是将“*”放在了下标的后面。
由于指针数组存储的都是地址,所以将变量i,与变量j的地址赋值给了指针数组p。
最后输出指针数组p中存储的地址和对应的值。
结构体指针变量
我们前面定义了指针指向了数组,解决了数组引用传递的问题。那么指针是否可以指向结构体,也能够解决结构体引用传递的问题呢?完全可以。
import "fmt"
type Teacher struct {
name string
age int
}
func main() {
p := &Teacher{name: "mark", age: 25}
p.age = 20
fmt.Println(*p)
}
ckage main
import “fmt”
func main() {
a := 100
var p *int
p = &a
fmt.Printf(“a的值为:%d\n”, a)
testPoint§
fmt.Printf(“调用后,a的值为:%d\n”, a)
}
func testPoint(p *int) {
*p = 666
}
输出如下:
```go
a的值为:100
调用后,a的值为:666
通过以上案例证实,指针作为参数进行传递时,为引用传递,也就是传递的地址。
数组指针
前面在讲解数组的时候,我们用数组作为函数参数,但是数组作为参数进行传递是值传递,如果想引用传递,可以使用数组指针。具体使用方式如下:
package main
import "fmt"
func main() {
a := [5]int{1, 2, 3, 4, 5}
testPoint(&a)
fmt.Println(a)
}
func testPoint(p *[5]int) {
// *p 的值 等于数组a的值
fmt.Println(*p)
(*p)[0] = 666
}
输出如下:
[1 2 3 4 5]
[666 2 3 4 5]
指针p,指向了数组a,对指针p的操作实际上是对数组a的操作,所以如果直接执行如下语句:fmt.Println(*p),会输出数组a中的值。也可以通过*p结合下标将对应的值取出来进行修改。最终在main函数中输出数组a,发现其元素也已经修改。
指针数组
上一小节,讲解到的是数组指针,也就是让一个指针指向数组 ,然后可以通过该指针来操作数组。还有一个概念叫指针数组,这两个概念很容混淆,指针数组指的是一个数组中存储的都是指针(也就是地址)。也就是一个存储了地址的数组。
下面通过一个案例,看一下指针数组的应用:
package main
import "fmt"
func main() {
var p [2]*int
i, j := 10, 20
p[0], p[1] = &i, &j
fmt.Println(p, *p[0], *p[1])
}
输出如下:
[0xc0000ac058 0xc0000ac070] 10 20
指针数组的定义方式,与数组指针定义方式是不一样的,注意指针数组是将“*”放在了下标的后面。
由于指针数组存储的都是地址,所以将变量i,与变量j的地址赋值给了指针数组p。
最后输出指针数组p中存储的地址和对应的值。
结构体指针变量
我们前面定义了指针指向了数组,解决了数组引用传递的问题。那么指针是否可以指向结构体,也能够解决结构体引用传递的问题呢?完全可以。
import "fmt"
type Teacher struct {
name string
age int
}
func main() {
p := &Teacher{name: "mark", age: 25}
p.age = 20
fmt.Println(*p)
}