指針
如果i是變量,通過 &i
語法來取得 i
的內存地址
如果i是指針,通過*i
語法來取得 i
的值
package main
import "fmt"
// 一個函數,接收的是數據類型
// 一個函數,接收的是數據類型的指針
// 接收到參數後,將參數值重新賦值,在從外面調用
// 發現普通的不會改變值,因爲在不同的作用域內
// 而傳遞指針的,會改變值,因爲操作的是內存地址
func zeroval(ival int) {
ival = 0
}
func zeroptr(iptr *int) {
*iptr = 0
}
func main() {
i := 1
fmt.Println("initial:", i)
zeroval(i)
fmt.Println("zeroval:", i)
zeroptr(&i)
fmt.Println("zeroptr:", i)
// 打印指針
fmt.Println("pointer:", &i)
}
結構體
這篇教程不錯
https://www.cnblogs.com/haiguixiansheng/p/10613754.html
package main
import "fmt"
// 這裏的 `person` 結構體包含了 `name` 和 `age` 兩個字段。
type person struct {
name string
age int
}
func main() {
// 使用這個語法創建了一個新的結構體元素。
fmt.Println(person{"Bob", 20})
// 你可以在初始化一個結構體元素時指定字段名字。
fmt.Println(person{name: "Alice", age: 30})
// 省略的字段將被初始化爲零值。
fmt.Println(person{name: "Fred"})
// `&` 前綴生成一個結構體指針。
fmt.Println(&person{name: "Ann", age: 40})
// 使用點來訪問結構體字段。
s := person{name: "Sean", age: 50}
fmt.Println(s.name)
// 也可以對結構體指針使用`.` - 指針會被自動解引用。
sp := &s
fmt.Println(sp.age)
// 結構體是可變的。
sp.age = 51
fmt.Println(sp.age)
}
方法
可以把結構體想象成一個類,這個方法區別於函數,屬於類的函數 叫方法。
package main
import "fmt"
// 定義結構體
type rect struct {
width int
height int
}
// 定義結構體的方法 面積
// 方法名叫area,返回值爲int
// 這個接收的是一個指針
func (r *rect) area() int {
return r.width * r.height
}
// 這個接收的是值,會有數據拷貝,其方法內的操作不會影響外面
func (r rect) perim() int {
return 2*r.width + 2*r.height
}
func main() {
r := rect{width: 10, height: 5}
fmt.Println("area: ", r.area())
fmt.Println("perim:", r.perim())
rp := &r
fmt.Println("area: ", rp.area())
fmt.Println("perim:", rp.perim())
}
area: 50
perim: 30
area: 50
perim: 30
值類型的變量和指針類型的變量 區別
https://www.cnblogs.com/zlingh/p/5701785.html
接口
package main
import "fmt"
import "math"
// 這裏是一個幾何體的基本接口。
// 把幾何體的方法都羅列出來
type geometry interface {
area() float64
perim() float64
}
// 矩形 結構體
type square struct {
width, height float64
}
// 圓形 結構體
type circle struct {
radius float64
}
// 定義矩形結構體的方法
func (s square) area() float64 {
return s.width * s.height
}
func (s square) perim() float64 {
return 2*s.width + 2*s.height
}
// 定義圓形結構體的方法
func (c circle) area() float64 {
return math.Pi * c.radius * c.radius
}
func (c circle) perim() float64 {
return 2 * math.Pi * c.radius
}
// 將接口當做參數,傳入到measure函數中,類型是geometry,形參是g
// 我們實際傳入的是結構體的實例
// 接口定義了一些方法名,這個實例也實現了對應的方法名
// 在函數中,就可以直接調用了
func measure(g geometry) {
fmt.Println(g)
fmt.Println(g.area())
fmt.Println(g.perim())
}
func main() {
// 創建結構體實例
s := square{width: 3, height: 4}
c := circle{radius: 5}
// 執行函數
measure(s)
measure(c)
}