main.go
// Go语言·方法
package main
// 包的本质是创建不同的文件夹
// go的每一个文件都是属于一个包的
// go以包的形式管理项目和文件目录。
// import "包的路径"
import (
utils "day20/model/utils"
_"fmt"
)
var content string = `
————————————————Go语言·方法————————————————————
一、方法
`
func main() {
utils.Entry()
}
utils.go
// Go语言·方法
package utils
import (
"fmt"
)
var layout string = "2006-01-02"
// 全局变量
var Author string = "Jhou Shuai"
// 全局变量
var Description string = "Go语言·方法"
//全局变量:使用反引号来定义多行字符串
var Content string = `
————————————————Go语言·方法————————————————————
一、方法
作用在指定的数据类型上的
自定义类型都可以有方法
type A struct {
Num int
}
// 方法 : 结构体A的方法test
func (a A) test (){}
二、方法的调用和传参机制原理
方法的调用和传参机制和函数基本一样,不一样的地方是方法调用
时候会把调用函数的变量也会作为参数传入到方法中。
如果变量是值类型,就进行值拷贝
如果变量是引用类型,就进行地址拷贝
三、方法的声明(定义)
func (recevier type) methodName (参数列表) (返回值列表) {
方法体
return 返回值。
}
0.参数列表:表示方法传入的参数
1.recevier type :表示这个方法和type这个类型进行绑定,或者说该方法作用于type类型
2.recevier type :type可以结构体,也可以是其他的自定义数据类型
3.recevier:就是type类型的一个变量(实例),比如:Person结构体的一个变量(实例)
4.返回值列表:表示返回的值,可以多个
5.方法主体:表示为了实现某一功能代码块
6.return数据不是必须的
四、方法的注意事项和细节讨论
1.结构体类型是值类型,在方法调用中,遵守值类型的传递机制,是值拷贝传递方式
2.如果希望在方法中,修改结构体变量的值。可以通过结构体指针的方式来处理
3.Golang中的方法作用在指定的数据类型上的。(即:和指定的数据类型绑定),因此自定义
类型都可以有方法,而不仅是struct,比如:int,float32等都可以有方法。
4.方法的访问范围控制的规则,和函数一样。方法名首字母小写,只能在本包访问,方法首字母
大写,可以在本包和其他包访问。
5.如果一个类型事项咯String()方法,那么fmt.Println默认会调用这个变量的String()进行
输出
五、函数和方法区别:
1.调用方式不一样:
函数调用:函数名(参数列表)
方法调用:变量名(实例名).方法名(参数列表)
2.对于普通的函数,接收者为值类型时,不能将指针类型的数据直接传递,接收者为指针类型时,
不能将值类型的数据直接传递。
3.对于方法:
接收者为值类型时,可以直接用指针类型的变量调用方法,但任然是值拷贝传递方式
接收者为指针类型时,可以用值类型的变量调用(编译器自动取地址),是引用传递,
var person Person
person.Name = "周帅"
// 形式上是传入地址,但是本质任然是值拷贝
(&person).structFuc()
fmt.Println(person.Name)
// 形式上是传入值类型,但是本质任然是地址拷贝
person.Rename()
fmt.Println(person.Name)
总结:
1.不管调用形式如何,真正决定是值拷贝还是地址拷贝,应该看方法和哪个类型绑定的
2.如果方法是和值类型绑定,则是值拷贝 比如:
func (person Person) structFuc() {} #值拷贝
3.如果方法是和指针类型绑定,则是地址拷贝 比如:
func (person *Person) Rename() {} #地址拷贝
`
type Person struct {
Name string
}
type Circle struct {
radius float64
}
type Student struct {
Name string
Age int
}
type MethodUtils struct{
}
type Calcuator struct {
Num1 float64
Num2 float64
}
/**
* [Init 入口]
* @author Jhou Shuai
* @datetime 2019-05-18T11:58:33+0800
*/
func Entry() {
var person Person
person.Name = "周帅"
// 形式上是传入地址,但是本质任然是值拷贝
(&person).structFuc()
fmt.Println(person.Name)
// 形式上是传入值类型,但是本质任然是地址拷贝
person.Rename()
fmt.Println(person.Name)
}
/**
* [func 给Person类型绑定一个方法]
* 给Person类型绑定一个方法
* structFuc方法只能通过Person类型的变量来调用,而不能直接调用,也不能用其他变量调用
* @author Jhou Shuai
* @datetime 2019-06-03T20:23:24+0800
* var person Person
person.Name = "周帅"
fmt.Println(person.getSum(100,20))
*/
func (person Person) structFuc() {
person.Name = "小可爱"
fmt.Println(person.Name)
}
func (person *Person) Rename() {
person.Name = "小宝贝儿"
fmt.Println(person.Name)
}
func (person Person) speak() {
fmt.Printf("%v是一个好人!",person.Name)
}
func (person Person) sum(n int) {
res := 0
for i:=1;i<=n;i++{
res +=i
}
fmt.Println(res)
}
func (person Person) getSum(n1 int,n2 int) int {
return n1 + n2
}
/*
var circle Circle
circle.radius = 6.0
// fmt.Println((&circle).area())
// 编译器:会自动加上&
fmt.Printf("circle变量的地址:%p \n", &circle)
fmt.Println(circle.area())
fmt.Println(circle.radius)
*/
func (circle *Circle) area() float64 {
circle.radius = 10
fmt.Printf("circle指向的地址:%p \n", circle)
// return 3.14 * (*circle).radius * (*circle).radius
return 3.14 * circle.radius * circle.radius
}
/*
stu := Student{
Name:"Faker",
Age : 19,
}
fmt.Println(&stu)
*/
func (stu *Student) String() string {
str := fmt.Sprintf("Name=[%v] Age=[%v] \n",stu.Name,stu.Age)
return str
}
/*
var mu MethodUtils
res := mu.area(2.5,6.7)
fmt.Println(res)
mu.JudgeNum(233)
mu.PrintFlower(5, 5, "~")
*/
func (mu *MethodUtils) area (len float64,width float64) float64 {
return len * width
}
func (mu *MethodUtils) JudgeNum (num int) {
if num%2 == 0 {
fmt.Println(num,"偶数")
}else{
fmt.Println(num,"奇数")
}
}
func (mu *MethodUtils) PrintFlower(n int ,m int, flower string) {
for i := 1; i <=n; i++ {
for j := 1; j <=m; j++ {
fmt.Print(flower)
}
fmt.Println()
}
}
/*
九九乘法表
*/
func (mu *MethodUtils) NineTable() {
var num int
fmt.Print("请输入一个数>>> ")
fmt.Scanln(&num)
for i := 1; i <= num ; i++ {
for j := 1; j <= i; j++ {
fmt.Printf("%v×%v=%v\t",j,i,i*j)
}
fmt.Println()
}
}
/*
用二维数组实现矩阵的转置
*/
func (mu *MethodUtils) Tranfer() {
var intArr [3][3]int = [...][3]int{{1,2,3},{4,5,6},{7,8,9}}
for _,values := range intArr {
for _ ,val := range values {
fmt.Print(val," ")
}
fmt.Println()
}
for i := 0; i < 3; i++ {
for j := 0; j <3; j++ {
fmt.Printf("%d ",intArr[j][i])
}
fmt.Println()
}
}
/*
var cal Calcuator
cal.Num1 = 3.3
cal.Num2 = 1.5
res := fmt.Sprintf("%.2f", cal.getRes('*'))
fmt.Println(res)
*/
func (calcuator *Calcuator) getRes(operator byte) float64 {
res := 0.0
switch operator{
case '+':
res = calcuator.Num1 + calcuator.Num2
case '-':
res = calcuator.Num1 - calcuator.Num2
case '*':
res = calcuator.Num1 * calcuator.Num2
case '/':
res = calcuator.Num1 / calcuator.Num2
default:
fmt.Println("输入有误!")
}
return res
}
网友评论