本篇文章介绍go语言中函数与方法的区别,因为方法与函数非常相似,在此分析两者的区别,便于区分。
一、函数概述
1、基本介绍
为完成某一功能的程序指令(语句)的集合,称为函数。
在Go中,函数分为: 自定义函数、系统函数
2、语法
func 函数名(形参列表)(返回值列表){
执行语句...
return 返回值列表
}
1)形参列表:表示函数的输入
2)函数中的语句:表示为了实现某一功能代码块
3)函数可以有返回值,也可以没有
3、案列代码
代码实现计算两个数的和和差,并返回结果
方法代码如下:
package others
/* 编写函数,计算两个数的和和差,并返回结果
分析: 1、需要传入两个参数
2、传入参数做加减运算
3、返回计算的结果
*/
// 代码实现
func Calculation(num1 , nun2 float64)(sum , dec float64) {
sum = num1 + nun2
dec = num1 - nun2
return
}
main函数调用如下:
package main
import (
"fmt"
transfer "go_code/grammar/function/transfer/code/others"
)
/*
编写函数,计算两个数的和和差,并返回结果
*/
func main(){
var num1 float64
var num2 float64
fmt.Println("请输入运算的两个数字")
fmt.Scanf("%f %f \n",&num1 ,&num2)
sum ,dec := transfer.Calculation(num1,num2)//方法的调用
fmt.Printf("计算结果sum= %.1f des=%.1f \n",sum ,dec)
}
测试代码:
请输入运算的两个数字
12 34
计算结果sum= 46.0 des=-22.0
二、方法概述
1、基本介绍
Golang中的方法是作用在指定的数据类型上的(即:和指定的数据类型绑定),因此自定义类型,都可以有方法,而不仅仅是struct。
2、语法
func (recevier type) methodName(参数列表) (返回值列表){
方法体
return 返回值
}
1)参数列表:表示方法输入
2)recevier type : 表示这个方法和type这个类型进行绑定,或者说该方法作用于type类型
3)receiver type : type可以是结构体,也可以其它的自定义类型
4)receiver : 就是type类型的一个变量(实例),比如 :Person结构体 的一个变量(实例)
5)返回值列表:表示返回的值,可以多个
6)方法主体:表示为了实现某一功能代码块
7)return 语句不是必须的。
3、案列代码:
/*结构体方法*/
type D struct {//结构体
Num int
}
func (a D) test() {//方法
fmt.Println(a.Num)
}
func StructMethodDemo4() {
//方法的使用
var a D //创建变量
a.test() //调用
}
三、函数与方法的区别
1、调用方式不一样
函数的调用方式: 函数名(实参列表)
方法的调用方式: 变量.方法名(实参列表)
参考上面的案例代码。
2、对于普通函数,接收者为值类型时,不能将指针类型的数据直接传递,反之亦然
案例:
package utils
import (
"fmt"
)
type Person struct{
Name string
}
func sayOk1(p *Person) {
}
func sayOk2(p Person) {
}
//方法和函数区别
func functionAndMethod() {
var p Person = Person{"tom"}
sayOk1(&p) // ok
sayOk1(p) //error
sayOk2(p) //ok
sayOk2(&p) // error
}
3、对于方法(如struct、int自定义类型的方法 ),接收者为值类型时,可以直接用指针类型的变量调用方法,反过来同样也可以。
案例:
package utils
import (
"fmt"
)
type Person struct{
Name string
}
func (p Person) test01() {
p.Name = "scott"
}
func (p *Person) test02() {
p.Name = "scott2" // p.Name 等价 (*p).Name
(*p).Name = "scott3" //标准的访问形式
}
//方法和函数区别
func functionAndMethod() {
var p Person = Person{"tom"}
p.test01() //ok
(&p).test01() // ok , 仍然等价于 p.test01(), 从形式上看是使用&p,但是本质仍然是 p
fmt.Println("main p.Name=", p.Name) // tom scott
//对于 func (p *Persons) test02() 的调用形式
(&p).test02() // ok!!!
p.test02()// ok!! 仍然等价于 (&p).test01(), 从形式上看是使用p,但是本质仍然是 &p
fmt.Println("main p.Name=", p.Name) // tom , scott2
}