Go 结构体方法
#### Go 結構體方法
本來今天有些事情忙的不準備更新內容了,后來提前完成了, 所以還是要更新了;
畢竟堅持本就是一件不容易的事情!加油,相信不管是大家還是我,都有一些事情想要做,那就堅持吧,剩下的交給天意吧;
昨天到今天上午一直在處理微信個人賬戶支付的事情,***大概就是如果個人沒有能力或者沒有權限開通微信支付功能,
而又想用微信的支付功能,那可能需要一些特殊的處理, 支付寶的功能同上***;
如果大家對個人支付感興趣的,可以找我哈^_^;
在這里給大家推薦一首歌
原唱: 趙方婧
---
##### 方法
在一些情況下定義方法: 如結構體的行為,需要用方法才能完成;
Go 中的方法是作用在指定的數據類型上的(和指定的數據類型綁定),因此***自定義類型都可以有方法,不僅僅是結構體***;
方法的聲明與調用:
type A struct {
Name string
}
func (a A) say(){
fmt.Println(a.Name)
}
說明:
1. func(a A) say() {} 表示結構體A有一個方法,名稱為say
2. (a A) 體現say 方法與A 類型綁定
案例: package mainimport "fmt"type Person struct {Name stringAge int } func (p Person) say(){fmt.Printf("I am %s and %d years old\n",p.Name,p.Age) } func main(){var p Personp.Name = "aaa"p.Age = 11var p2 Personp2.Name = "bbb"p2.Age = 22// 調用實例方法p.say() // I am aaa and 11 years oldp2.say() //I am bbb and 22 years old }
說明:
1. say 方法與Person 類型綁定
2. say 方法只能通過Person 類型的變量來調用,不能直接調用,也不能使用其它類型的變量調用;
3. say 方法的調用方式與其它OOP 語言有很大不同,***沒有靜態方法***;
4. func (p Person) say(){} p 表示哪個Person 實例調用,這個p 就是它的副本,與函數傳參相似;
5. p***稱為接收者***,可以自定義,一般建議起一些可以直觀體驗類型的名字;
---
再來體驗一下例子: package mainimport ("fmt" ) type Student struct {Name stringAge intSkills []string } // 這里類似引用 func (s *Student)Learn(skill string) {// 通過學習,會一個技能// append 底層會自動makes.Skills = append(s.Skills,skill) } func (s Student) Show(){for _,skill := range s.Skills {fmt.Printf("I am %s,I am %d years old,and %sing is my skill\n",s.Name,s.Age,skill)} } func main(){var s1 Students1.Name = "小明"s1.Age = 20s1.Learn("fish")s1.Learn("learn")var s2 Students2.Name = "小紅"s2.Age = 18s2.Learn("Sing")s2.Learn("paint")// 調用方法s1.Show()s2.Show()//I am 小明,I am 20 years old,and fishing is my skill//I am 小明,I am 20 years old,and learning is my skill//I am 小紅,I am 18 years old,and Singing is my skill//I am 小紅,I am 18 years old,and painting is my skill }
說明:
上面的一個小例子里面綜合了前面學習的知識,還有本節要學習的知識,學習完本節應該都能理解了;
##### 方法的調用與傳參機制原理
方法的調用和傳參機制和函數基本一樣,不一樣的地方是方法調用時,會將調用方法的變量當做實參也傳遞給方法;
如果接收者是值類型進行值拷貝,如果接收者是引用類型進行地址拷貝; package mainimport "fmt" type Student struct {Name stringAge int } func (s Student) setName(){// 接收者為實例變量的副本,在方法內更改值不會影響原來的值s.Name = "aaaaaa" } func (s *Student) setAge(){// 接收者為實例變量地址的副本,在方法內更改值會改變原來的值s.Age = 21 } func main(){var s1 Studentvar s2 Students1.Name = "a"s1.Age = 10s2.Name = "b"s2.Age = 10s1.setName()fmt.Println(s1)// {a 10}s2.setAge()fmt.Println(s2) //{b 21} }
方法的注意事項:
1. 結構體是值類型,在方法調用中遵守值類型的傳遞機制;
2. 如果需要修改結構體變量的值,類似上述例子,通過結構體指針的方式處理;
3. Go 中的方法作用在指定的數據類型的方法上(與指定的數據類型綁定);
4. 方法的控制范圍的規則與函數一樣,方法名首字母小寫,只能在本包內訪問,方法首字母大寫,可以在本包和其它包訪問;
5. 如果一個結構體實現了String() 方法,那么fmt.Println() 默認會調用String 方法進行輸出;
6. 對于方法接收者是值類型時,可以直接用指針類型的變量調用,反過來同樣可以;
7. 不管接收者是值類型還是引用類型都可以直接使用實例變量調用方法;
案例: package mainimport "fmt" type Student struct {Name stringAge int } //也可以使用值類型調用此方法 func (s *Student) setName(){s.Name = "bbbb" } //也可以使用指針類型調用此方法 func (s Student) showName(){fmt.Println(s.Name) } // 默認fmt.Println 會調用此方法 func (s Student) String() string{return fmt.Sprintf("I am %s,i am %d years old",s.Name,s.Age) } func main(){var s Students.Name = "a"s.Age = 20fmt.Println(s) // I am a,i am 20 years olds.setName() // 值類型的調用接收者為指針類型的方法s.showName() // bbbbfmt.Println(s) // I am bbbb,i am 20 years oldvar s1 *Student = new(Student)s1.Name = "b"s1.Age = 10fmt.Println(s1) // I am b,i am 10 years olds1.setName() //s1.showName() // bbbb 指針類型的調用接收者為值類型的方法// 在這里需要說一下// 標準的調用 方式應該是(*s1).showName()// Go 編譯器在底層自動做了解引用,所以可以簡化成s1.showName // 總之,不管是指針接收者還是值接收者,統一使用實例.方法名就可以; fmt.Println(s1) //I am bbbb,i am 10 years old }
---
總結一下:
不管調用形式如何(調用者是值類型還是引用類型),真正決定是值拷貝還是地址拷貝的,要看方法的接收者是什么類型;
如: (p Person) 則進行的是值拷貝,(p *Person) 是地址拷貝;
今天這些內容,有點繞,暫時就這些吧,學習一種新的編程語言時需要將其它的編程風格摒棄掉,希望一起進步;
個人微信公眾號上會發最新的內容,歡迎關注一同交流學習
本來今天有些事情忙的不準備更新內容了,后來提前完成了, 所以還是要更新了;
畢竟堅持本就是一件不容易的事情!加油,相信不管是大家還是我,都有一些事情想要做,那就堅持吧,剩下的交給天意吧;
昨天到今天上午一直在處理微信個人賬戶支付的事情,***大概就是如果個人沒有能力或者沒有權限開通微信支付功能,
而又想用微信的支付功能,那可能需要一些特殊的處理, 支付寶的功能同上***;
如果大家對個人支付感興趣的,可以找我哈^_^;
在這里給大家推薦一首歌
原唱: 趙方婧
---
##### 方法
在一些情況下定義方法: 如結構體的行為,需要用方法才能完成;
Go 中的方法是作用在指定的數據類型上的(和指定的數據類型綁定),因此***自定義類型都可以有方法,不僅僅是結構體***;
方法的聲明與調用:
type A struct {
Name string
}
func (a A) say(){
fmt.Println(a.Name)
}
說明:
1. func(a A) say() {} 表示結構體A有一個方法,名稱為say
2. (a A) 體現say 方法與A 類型綁定
案例: package mainimport "fmt"type Person struct {Name stringAge int } func (p Person) say(){fmt.Printf("I am %s and %d years old\n",p.Name,p.Age) } func main(){var p Personp.Name = "aaa"p.Age = 11var p2 Personp2.Name = "bbb"p2.Age = 22// 調用實例方法p.say() // I am aaa and 11 years oldp2.say() //I am bbb and 22 years old }
說明:
1. say 方法與Person 類型綁定
2. say 方法只能通過Person 類型的變量來調用,不能直接調用,也不能使用其它類型的變量調用;
3. say 方法的調用方式與其它OOP 語言有很大不同,***沒有靜態方法***;
4. func (p Person) say(){} p 表示哪個Person 實例調用,這個p 就是它的副本,與函數傳參相似;
5. p***稱為接收者***,可以自定義,一般建議起一些可以直觀體驗類型的名字;
---
再來體驗一下例子: package mainimport ("fmt" ) type Student struct {Name stringAge intSkills []string } // 這里類似引用 func (s *Student)Learn(skill string) {// 通過學習,會一個技能// append 底層會自動makes.Skills = append(s.Skills,skill) } func (s Student) Show(){for _,skill := range s.Skills {fmt.Printf("I am %s,I am %d years old,and %sing is my skill\n",s.Name,s.Age,skill)} } func main(){var s1 Students1.Name = "小明"s1.Age = 20s1.Learn("fish")s1.Learn("learn")var s2 Students2.Name = "小紅"s2.Age = 18s2.Learn("Sing")s2.Learn("paint")// 調用方法s1.Show()s2.Show()//I am 小明,I am 20 years old,and fishing is my skill//I am 小明,I am 20 years old,and learning is my skill//I am 小紅,I am 18 years old,and Singing is my skill//I am 小紅,I am 18 years old,and painting is my skill }
說明:
上面的一個小例子里面綜合了前面學習的知識,還有本節要學習的知識,學習完本節應該都能理解了;
##### 方法的調用與傳參機制原理
方法的調用和傳參機制和函數基本一樣,不一樣的地方是方法調用時,會將調用方法的變量當做實參也傳遞給方法;
如果接收者是值類型進行值拷貝,如果接收者是引用類型進行地址拷貝; package mainimport "fmt" type Student struct {Name stringAge int } func (s Student) setName(){// 接收者為實例變量的副本,在方法內更改值不會影響原來的值s.Name = "aaaaaa" } func (s *Student) setAge(){// 接收者為實例變量地址的副本,在方法內更改值會改變原來的值s.Age = 21 } func main(){var s1 Studentvar s2 Students1.Name = "a"s1.Age = 10s2.Name = "b"s2.Age = 10s1.setName()fmt.Println(s1)// {a 10}s2.setAge()fmt.Println(s2) //{b 21} }
方法的注意事項:
1. 結構體是值類型,在方法調用中遵守值類型的傳遞機制;
2. 如果需要修改結構體變量的值,類似上述例子,通過結構體指針的方式處理;
3. Go 中的方法作用在指定的數據類型的方法上(與指定的數據類型綁定);
4. 方法的控制范圍的規則與函數一樣,方法名首字母小寫,只能在本包內訪問,方法首字母大寫,可以在本包和其它包訪問;
5. 如果一個結構體實現了String() 方法,那么fmt.Println() 默認會調用String 方法進行輸出;
6. 對于方法接收者是值類型時,可以直接用指針類型的變量調用,反過來同樣可以;
7. 不管接收者是值類型還是引用類型都可以直接使用實例變量調用方法;
案例: package mainimport "fmt" type Student struct {Name stringAge int } //也可以使用值類型調用此方法 func (s *Student) setName(){s.Name = "bbbb" } //也可以使用指針類型調用此方法 func (s Student) showName(){fmt.Println(s.Name) } // 默認fmt.Println 會調用此方法 func (s Student) String() string{return fmt.Sprintf("I am %s,i am %d years old",s.Name,s.Age) } func main(){var s Students.Name = "a"s.Age = 20fmt.Println(s) // I am a,i am 20 years olds.setName() // 值類型的調用接收者為指針類型的方法s.showName() // bbbbfmt.Println(s) // I am bbbb,i am 20 years oldvar s1 *Student = new(Student)s1.Name = "b"s1.Age = 10fmt.Println(s1) // I am b,i am 10 years olds1.setName() //s1.showName() // bbbb 指針類型的調用接收者為值類型的方法// 在這里需要說一下// 標準的調用 方式應該是(*s1).showName()// Go 編譯器在底層自動做了解引用,所以可以簡化成s1.showName // 總之,不管是指針接收者還是值接收者,統一使用實例.方法名就可以; fmt.Println(s1) //I am bbbb,i am 10 years old }
---
總結一下:
不管調用形式如何(調用者是值類型還是引用類型),真正決定是值拷貝還是地址拷貝的,要看方法的接收者是什么類型;
如: (p Person) 則進行的是值拷貝,(p *Person) 是地址拷貝;
今天這些內容,有點繞,暫時就這些吧,學習一種新的編程語言時需要將其它的編程風格摒棄掉,希望一起進步;
個人微信公眾號上會發最新的內容,歡迎關注一同交流學習
轉載于:https://www.cnblogs.com/Mail-maomao/p/11458961.html
總結
- 上一篇: Go 面向对象之结构体
- 下一篇: Go 面向对象编程应用