Golang-100-Days/day14_第1节_方法.md at master - GitHub
文章推薦指數: 80 %
Golang - 100天从新手到大师. Contribute to rubyhan1314/Golang-100-Days development by creating an account on GitHub.
Skiptocontent
{{message}}
rubyhan1314
/
Golang-100-Days
Public
Notifications
Star
4.2k
Fork
1.4k
Code
Issues
15
Pullrequests
4
Actions
Projects
0
Wiki
Security
Insights
More
Code
Issues
Pullrequests
Actions
Projects
Wiki
Security
Insights
Permalink
master
Branches
Tags
Couldnotloadbranches
Nothingtoshow
Loading
{{refName}}
default
Couldnotloadtags
Nothingtoshow
{{refName}}
default
Loading
Golang-100-Days/Day01-15(Go语言基础)/day14_第1节_方法.md
Gotofile
Gotofile
T
Gotoline
L
Copypath
Copypermalink
Cannotretrievecontributorsatthistime
方法
1.1什么是方法
1.2方法的语法
1.3方法和函数
1.4变量作用域
1.5method继承
1.6method重写
362lines(261sloc)
7.46KB
Raw
Blame
OpenwithDesktop
Viewraw
Viewblame
方法
@author:韩茹
版权所有:北京千锋互联科技有限公司
1.1什么是方法
Go语言中同时有函数和方法。
一个方法就是一个包含了接受者的函数,接受者可以是命名类型或者结构体类型的一个值或者是一个指针。
所有给定类型的方法属于该类型的方法集
方法只是一个函数,它带有一个特殊的接收器类型,它是在func关键字和方法名之间编写的。
接收器可以是struct类型或非struct类型。
接收方可以在方法内部访问。
方法能给用户自定义的类型添加新的行为。
它和函数的区别在于方法有一个接收者,给一个函数添加一个接收者,那么它就变成了方法。
接收者可以是值接收者,也可以是指针接收者。
在调用方法的时候,值类型既可以调用值接收者的方法,也可以调用指针接收者的方法;指针类型既可以调用指针接收者的方法,也可以调用值接收者的方法。
也就是说,不管方法的接收者是什么类型,该类型的值和指针都可以调用,不必严格符合接收者的类型。
1.2方法的语法
定义方法的语法
func(tType)methodName(parameterlist)(returnlist){
}
funcfuncName(parameterlist)(returnlist){
}
实例代码:
packagemain
import(
"fmt"
)
typeEmployeestruct{
namestring
salaryint
currencystring
}
/*
displaySalary()methodhasEmployeeasthereceivertype
*/
func(eEmployee)displaySalary(){
fmt.Printf("Salaryof%sis%s%d",e.name,e.currency,e.salary)
}
funcmain(){
emp1:=Employee{
name:"SamAdolf",
salary:5000,
currency:"$",
}
emp1.displaySalary()//CallingdisplaySalary()methodofEmployeetype
}
可以定义相同的方法名
示例代码:
packagemain
import(
"fmt"
"math"
)
typeRectanglestruct{
width,heightfloat64
}
typeCirclestruct{
radiusfloat64
}
func(rRectangle)area()float64{
returnr.width*r.height
}
//该method属于Circle类型对象中的方法
func(cCircle)area()float64{
returnc.radius*c.radius*math.Pi
}
funcmain(){
r1:=Rectangle{12,2}
r2:=Rectangle{9,4}
c1:=Circle{10}
c2:=Circle{25}
fmt.Println("Areaofr1is:",r1.area())
fmt.Println("Areaofr2is:",r2.area())
fmt.Println("Areaofc1is:",c1.area())
fmt.Println("Areaofc2is:",c2.area())
}
运行结果
Areaofr1is:24
Areaofr2is:36
Areaofc1is:314.1592653589793
Areaofc2is:1963.4954084936207
虽然method的名字一模一样,但是如果接收者不一样,那么method就不一样
method里面可以访问接收者的字段
调用method通过.访问,就像struct里面访问字段一样
1.3方法和函数
既然我们已经有了函数,为什么还要使用方法?
示例代码:
packagemain
import(
"fmt"
)
typeEmployeestruct{
namestring
salaryint
currencystring
}
/*
displaySalary()methodconvertedtofunctionwithEmployeeasparameter
*/
funcdisplaySalary(eEmployee){
fmt.Printf("Salaryof%sis%s%d",e.name,e.currency,e.salary)
}
funcmain(){
emp1:=Employee{
name:"SamAdolf",
salary:5000,
currency:"$",
}
displaySalary(emp1)
}
在上面的程序中,displaySalary方法被转换为一个函数,而Employeestruct作为参数传递给它。
这个程序也产生了相同的输出:SalaryofSamAdolfis$5000.。
为什么我们可以用函数来写相同的程序呢?有以下几个原因
Go不是一种纯粹面向对象的编程语言,它不支持类。
因此,类型的方法是一种实现类似于类的行为的方法。
相同名称的方法可以在不同的类型上定义,而具有相同名称的函数是不允许的。
假设我们有一个正方形和圆形的结构。
可以在正方形和圆形上定义一个名为Area的方法。
这是在下面的程序中完成的。
1.4变量作用域
作用域为已声明标识符所表示的常量、类型、变量、函数或包在源代码中的作用范围。
Go语言中变量可以在三个地方声明:
函数内定义的变量称为局部变量
函数外定义的变量称为全局变量
函数定义中的变量称为形式参数
局部变量
在函数体内声明的变量称之为局部变量,它们的作用域只在函数体内,参数和返回值变量也是局部变量。
全局变量
在函数体外声明的变量称之为全局变量,首字母大写全局变量可以在整个包甚至外部包(被导出后)使用。
packagemain
import"fmt"
/*声明全局变量*/
vargint
funcmain(){
/*声明局部变量*/
vara,bint
/*初始化参数*/
a=10
b=20
g=a+b
fmt.Printf("结果:a=%d,b=%dandg=%d\n",a,b,g)
}
结果
结果:a=10,b=20andg=30
形式参数
形式参数会作为函数的局部变量来使用
指针作为接收者
若不是以指针作为接收者,实际只是获取了一个copy,而不能真正改变接收者的中的数据
func(b*Box)SetColor(cColor){
b.color=c
}
示例代码
packagemain
import(
"fmt"
)
typeRectanglestruct{
width,heightint
}
func(r*Rectangle)setVal(){
r.height=20
}
funcmain(){
p:=Rectangle{1,2}
s:=p
p.setVal()
fmt.Println(p.height,s.height)
}
结果
202
如果没有那个*,则值就是22
1.5method继承
method是可以继承的,如果匿名字段实现了一个method,那么包含这个匿名字段的struct也能调用该method
packagemain
import"fmt"
typeHumanstruct{
namestring
ageint
phonestring
}
typeStudentstruct{
Human//匿名字段
schoolstring
}
typeEmployeestruct{
Human//匿名字段
companystring
}
func(h*Human)SayHi(){
fmt.Printf("Hi,Iam%syoucancallmeon%s\n",h.name,h.phone)
}
funcmain(){
mark:=Student{Human{"Mark",25,"222-222-YYYY"},"MIT"}
sam:=Employee{Human{"Sam",45,"111-888-XXXX"},"GolangInc"}
mark.SayHi()
sam.SayHi()
}
运行结果:
Hi,IamMarkyoucancallmeon222-222-YYYY
Hi,IamSamyoucancallmeon111-888-XXXX
1.6method重写
packagemain
import"fmt"
typeHumanstruct{
namestring
ageint
phonestring
}
typeStudentstruct{
Human//匿名字段
schoolstring
}
typeEmployeestruct{
Human//匿名字段
companystring
}
//Human定义method
func(h*Human)SayHi(){
fmt.Printf("Hi,Iam%syoucancallmeon%s\n",h.name,h.phone)
}
//Employee的method重写Human的method
func(e*Employee)SayHi(){
fmt.Printf("Hi,Iam%s,Iworkat%s.Callmeon%s\n",e.name,
e.company,e.phone)//Yesyoucansplitinto2lineshere.
}
funcmain(){
mark:=Student{Human{"Mark",25,"222-222-YYYY"},"MIT"}
sam:=Employee{Human{"Sam",45,"111-888-XXXX"},"GolangInc"}
mark.SayHi()
sam.SayHi()
}
运行结果:
Hi,IamMarkyoucancallmeon222-222-YYYY
Hi,IamSam,IworkatGolangInc.Callmeon111-888-XXXX
方法是可以继承和重写的
存在继承关系时,按照就近原则,进行调用
千锋Go语言的学习群:784190273
作者B站:
https://space.bilibili.com/353694001
对应视频地址:
https://www.bilibili.com/video/av56018934
https://www.bilibili.com/video/av47467197
源代码:
https://github.com/rubyhan1314/go_advanced
Go
Youcan’tperformthatactionatthistime.
Yousignedinwithanothertaborwindow.Reloadtorefreshyoursession.
Yousignedoutinanothertaborwindow.Reloadtorefreshyoursession.
延伸文章資訊
- 1100 Days of Learning Go : r/golang - Reddit
15 votes, 21 comments. Just starting to learn GO and I plan to do 100 days here https://github.co...
- 2Golang - 100天从新手到大师 - GitHub中文社区
Golang-100-Days · 编程语言 · 是否国产 · 最近更新.
- 3100 days of Go learning | GolangRepo
This repository is a journal of my path to learning GO. By the end of the 100 days, you should be...
- 42021-11-04-01-19-22-Golang-100-Days-master.zip - 下载
2021-11-04-01-19-22-Golang-100-Days-master.zip.
- 5Como foi fazer o 100 Days of Code com Golang? - DEV ...
Eae pessoal tudo tranquilo? dia 5 de março eu terminei o 100 days of code \o/ e fiz utilizando ap...