Golang-100-Days/day14_第1节_方法.md at master - GitHub

文章推薦指數: 80 %
投票人數:10人

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.



請為這篇文章評分?