Go语言基础总结
导入库
关键字import
一般形式:
import (
"fmt" //包 "github.com/gin-gonic/gin" //库)
注意: 如果只使用库中的部分功能可以使用***“ _ ”***来表示省略未使用的部分
import (
"fmt" _ "github.com/gin-gonic/gin")
标准输入输出
在Go语言中,标准输入和标准输出是通过os包中的Stdin和Stdout来实现的。
要从标准输入读取数据,可以使用bufio包中的NewReader函数创建一个Reader对象,然后使用其ReadString方法来读取一行字符串。示例如下:
package main
import (
"bufio"
"fmt"
"os"
)
func main() {
reader := bufio.NewReader(os.Stdin)
fmt.Print("请输入一个字符串: ")
str, _ := reader.ReadString('\n')
fmt.Println("你输入的字符串是:", str)
}
要向标准输出打印数据,可以使用fmt包中的Print、Printf和Println等函数。示例如下:
package main
import "fmt"
func main() {
fmt.Print("这是一个普通的打印输出")
fmt.Printf("这是一个格式化的输出: %d\n", 123)
fmt.Println("这是一个带换行的输出")
}
基本数据类型
-
布尔类型(bool):表示真假值,只有两个取值:true和false。
-
整数类型:包括有符号整数和无符号整数。有符号整数类型有int8、int16、int32和int64,无符号整数类型有uint8、uint16、uint32和uint64。还有一个特殊的整数类型是int,它的大小在不同平台上可能不同。
-
浮点类型:包括float32和float64两种。float32精度为32位,float64精度为64位。
-
复数类型:包括complex64和complex128两种。complex64由两个float32组成,一个表示实部,一个表示虚部;complex128由两个float64组成。
-
字符串类型(string):表示一串字符,使用双引号或反引号括起来。
-
字符类型(rune):表示一个Unicode字符,使用单引号括起来。
-
错误类型(error):表示一个错误,通常用于函数返回错误信息。
-
指针类型(pointer):表示一个内存地址。
-
数组类型(array):表示一组相同类型的固定长度的数据。
-
切片类型(slice):表示一个动态长度的序列,是对数组的封装。
-
映射类型(map):表示一组键值对的集合。
-
结构体类型(struct):表示一组字段的集合,每个字段有自己的类型和名称。
-
接口类型(interface):表示一组方法的集合,用于定义对象的行为。
循环与条件判断
判断
1. 条件判断(if - else)
if <条件> {
// 如果条件为真,则执行这里的代码} else {
// 如果条件为假,则执行这里的代码}
2. 带初始化语句的条件判断语句(if-else)
if initialization; condition {
// 如果条件为真,则执行这里的代码
} else {
// 如果条件为假,则执行这里的代码
}
go语言方法
方法声明
func (t T) F() {}
指针接收器和值接收器型
在Go语言中,方法可以通过指针接收器或值接收器来定义。
指针接收器型方法:指针接收器使用指向类型的指针作为接收器。这种方法可以修改接收器指向的值,也可以避免在方法调用时进行值的拷贝。定义指针接收器型方法的语法如下:
func (p *Type) methodName() {
// 方法的实现
}
值接收器型方法:值接收器使用类型的值作为接收器。这种方法在调用时会对接收器进行值的拷贝,因此不会修改原始值。定义值接收器型方法的语法如下:
func (v Type) methodName() {
// 方法的实现
}
使用指针接收器型方法可以修改接收器指向的值,而使用值接收器型方法则不能修改接收器指向的值。一般来说,如果方法需要修改接收器指向的值,或者接收器是一个大型的结构体,推荐使用指针接收器型方法;如果方法不需要修改接收器指向的值,并且接收器是一个小型的值类型,可以使用值接收器型方法。
示例代码:
package main
import "fmt"
type Point struct {
x, y int
}
// 指针接收器型方法
func (p *Point) Move(dx, dy int) {
p.x += dx
p.y += dy
}
// 值接收器型方法
func (p Point) Distance() float64 {
return math.Sqrt(float64(p.x*p.x + p.y*p.y))
}
func main() {
p := Point{1, 2}
p.Move(2, 3)
fmt.Println(p) // 输出:{3 5}
d := p.Distance()
fmt.Println(d) // 输出:5.830951894845301
}
在上面的代码中,Move方法使用了指针接收器,可以修改Point结构体的值;Distance方法使用了值接收器,不会修改Point结构体的值。
何时使用指针接收与值接收
通常,当调用者应该可以看到方法内对接收器所做的更改时,可以使用指针接收器。
指针接收器也可用于复制数据结构成本高昂的地方。考虑一个具有许多字段的结构。将此结构用作方法中的值接收器将需要复制整个结构,这将是昂贵的。在这种情况下,如果使用指针接收器,则不会复制结构,而在方法中只会使用指向它的指针。
在所有其他情况下,可以使用值接收器。
命名冲突
a. 接收者定义的方法名不能重复, 例如:
package main
type T struct{}
func (T) F() {}
func (T) F(a string) {}
func main() {
t := T{}
t.F()
}
运行代码我们会得到 method redeclared: T.F 类似错误。
b. 结构体方法名不能和字段重复,例如:
package main
type T struct{
F string
}
func (T) F(){}
func main() {
t := T{}
t.F()
}
运行代码我们会得到 : type T has both field and method named F 类似错误。
同一个接收者的方法名不能重复 (没有重载);如果是结构体,方法名不能和字段重复。
接收者可以同时为值和指针
在 Go 语言中,方法的接收者可以同时为值或者指针,例如:
package main
type T struct{}
func (T) F() {}
func (*T) N() {}
func main() {
t := T{}
t.F()
t.N()
t1 := &T{} // 指针类型
t1.F()
t1.N()
}
可以看到无论值类型 T 还是指针类型 &T 都可以同时访问 F 和 N 方法。