1.go語言的接口是怎么實現
接口(interface)是一種類型,它定義了一組方法的集合。任何類型只要實現了接口中定義的所有方法,就被認為實現了該接口。
代碼的實現
package mainimport "fmt"// 定義接口
type Shape interface {Area() float64Perimeter() float64
}// 定義實現接口的類型
type Rectangle struct {Width float64Height float64
}// 實現接口方法
func (r Rectangle) Area() float64 {return r.Width * r.Height
}func (r Rectangle) Perimeter() float64 {return 2 * (r.Width + r.Height)
}func main() {// 使用接口var s Shaperect := Rectangle{Width: 4, Height: 5}s = rectfmt.Println("面積:", s.Area()) // 輸出: 面積: 20fmt.Println("周長:", s.Perimeter()) // 輸出: 周長: 18
}
理解與記憶方法
1接口是方法的集合:接口定義了一組方法,任何類型實現了這些方法就實現了接口。
2隱式實現:Go 不需要顯式聲明實現某個接口,只要類型的方法集包含接口的所有方法即可。
3空接口:interface{} 是最通用的接口,可存儲任何類型值,用于靈活性需求。
4接口值的內部結構:接口值包含動態類型信息和實際數據值,支持類型斷言和類型切換。
5鴨子類型:如果一個東西走起來像鴨子,叫起來也像鴨子,那么它就是鴨子。即,只要類型實現了接口的方法,就被認為實現了接口。
2.go語言使用斷言時會發生拷貝嗎
**類型斷言是否會發生拷貝,取決于接口值的存儲方式
場景 1:接口存儲的是值類型(直接拷貝)
場景 2:接口存儲的是指針類型(不拷貝)
3.go語言中如何訪問私有成員
1.導出公有方法【推薦度:★★★★★】(get和set)
package mainimport "fmt"// 定義一個結構體
type Person struct {name string // 私有字段age int // 私有字段
}// 導出 Get 方法 - 獲取 name
func (p *Person) GetName() string {return p.name
}// 導出 Set 方法 - 設置 name
func (p *Person) SetName(newName string) {p.name = newName
}// 導出 Get 方法 - 獲取 age
func (p *Person) GetAge() int {return p.age
}// 導出 Set 方法 - 設置 age
func (p *Person) SetAge(newAge int) {if newAge >= 0 {p.age = newAge} else {fmt.Println("年齡不能為負數")}
}func main() {// 創建 Person 實例person := Person{name: "張三",age: 25,}// 調用 Get 方法fmt.Println("姓名:", person.GetName()) // 輸出: 姓名: 張三fmt.Println("年齡:", person.GetAge()) // 輸出: 年齡: 25// 調用 Set 方法person.SetName("李四")person.SetAge(30)fmt.Println("新姓名:", person.GetName()) // 輸出: 新姓名: 李四fmt.Println("新年齡:", person.GetAge()) // 輸出: 新年齡: 30// 測試設置非法年齡person.SetAge(-5) // 輸出: 年齡不能為負數
}
2.反射(reflect包)【推薦度:★★★】
導入反射包:在代碼中導入 reflect 包。
獲取反射對象:使用 reflect.TypeOf 獲取類型的反射對象,reflect.ValueOf 獲取值的反射對象。
獲取字段:通過反射對象的 FieldByName 或 Fields 方法獲取結構體的字段。
設置可導出性:如果字段是私有的(小寫開頭),需要通過反射設置其可導出性(CanSet)。
訪問和修改字段:使用反射對象的 Interface 方法獲取字段的值,Set 方法修改字段的值
package mainimport ("fmt""reflect"
)// 定義一個結構體
type Person struct {name string // 私有字段age int // 私有字段
}func main() {// 創建 Person 實例person := Person{name: "張三",age: 25,}// 使用反射訪問私有字段accessPrivateField(&person)
}// 使用反射訪問私有字段
func accessPrivateField(obj interface{}) {// 獲取反射對象val := reflect.ValueOf(obj).Elem() // 獲取指針對應的值// 獲取 name 字段nameField := val.FieldByName("name")if nameField.CanSet() {fmt.Println("name 字段值:", nameField.Interface())// 修改 name 字段值nameField.SetString("李四")}// 獲取 age 字段ageField := val.FieldByName("age")if ageField.CanSet() {fmt.Println("age 字段值:", ageField.Interface())// 修改 age 字段值ageField.SetInt(30)}// 打印修改后的值fmt.Println("修改后的 person:", obj.(*Person))
}
3.同包內直接訪問【推薦度:★★★★】
?
自學go語言筆記,希望我們可以一起學習!