GoLang:函数、方法

学习自:Go教材80、117页

1、函数

A、函数

函数定义在main函数之外

func 函数名(参数列表)(返回类型列表) {
    语句;
    return 返回值;
}

①无参函数

func say(){
    fmt.println("Hello world!")
}

②有参无返回值

func say(name string){
    fmt.Println("Hello ",name)
}

③无参有返回值(若返回值只有一个,则不用加括号)

func sum() int {
    return 1+1
}

④有参有返回值

func sum(a int,b int) int {
    return a+b
}

⑤指定返回值的名称

func sum()(res int){
    res=1+1
    return
}

⑥多个返回值(完全体)

func calculate(a int,b int)(sum int,sub int){
    sum=a+b
    sub=a-b
    return
}

⑦相同(返回值/参数)类型,只写最后一个即可

func calculate(a,b int)(sum,sub int){
    sum=a+b
    sub=a-b
}

补充:

函数的定义位置在使用位置之前还是之后对函数的正常使用无影响。

B、值传递、引用传递

值类型:int、float、bool、string、数组、struct

引用类型:指针、slice、map、channel

说明:

  • 值类型在中分配空间,引用类型在
  • 作为函数参数传递到函数内时,值传递拷贝传递引用传递引用传递
  • 在函数体内对值参数的修改不会影响函数外的值,对引用类型参数的修改会影响到函数外的值

例子

值传递

引用传递

C、匿名函数

应用场景:

  • 某个函数只用到了一次
  • 执行一些不确定的操作

①直接调用

func (s string){
    fmt.Println(s)
}("hello lnj")

②保存到变量

a:=func(s string){
    fmt.Println(s)
}
a("hello lnj")

③作为参数

test( func(s string){
    fmt.Println(s)
})

func test(f func(s string)){
    f("hello lnj")
}

④作为返回值

res:=test()
res(10,20)

func test() func(int,int){
    return func(a int,b int){
        fmt.Println(a+b)
    }
}

D、闭包

闭包是一个特殊的匿名函数,它是匿名函数和相关引用环境组成的一个整体。

只要在匿名函数中用到了外界的变量,那么这个匿名函数就是一个闭包,在闭包中对外界变量的修改和直接在外界修改的效果相同。只要闭包还在使用外部变量,那么外部变量就会一直存在(哪怕这个变量不是在main中定义)

①经典闭包

 ②修改外部变量,导致外部变量自身也会发生变化

 ③闭包未结束,则外部变量一直存在(哪怕这个外部变量并非在main中定义的),且一直维持同一个变量而非新创建

E、延迟调用defer

常用于释放资源、解除锁定、错误处理

作用方式:无论在何处注册defer,它都会在所属函数执行完毕之后才会执行,并且如果注册了多个defer,会按照后进先出的原则执行。

基于这种特性,可以在资源打开的同时,就用defer来声明它的关闭,因为无论如何defer都会在所属函数执行完毕后才会执行

F、init函数

golang中存在两个保留的函数:

  • init函数:应用于所有的package
  • main函数:只能应用于main包

这两个函数在定义时不能有参数、返回值

init函数的作用:处理当前文件的初始化操作,存放一些准备工作。

说明

  • go会自动调用main、init,因此我们不能手动调用它们。
  • main包必须包含一个main(),但每个包中的init()都是可选的
  • 一个包中可以写任意多个init(),但是最好还是只写一个init
  • 执行顺序:main包→常量→全局变量→init()→main()→Exit

     执行顺序:const→var global...→init()→main()→exit

  • 多个包代码的执行顺序

2、方法

1)定义

1
2
3
func (接收者 数据类型)方法名(形参)(返回值){
    方法体
}

2)说明

①方法本质上是一个特殊函数,只是它是和某种属性类型绑定在一起的;

②方法一般用于将函数结构体进行绑定,让结构体除了保存数据外还能具备某些行为

函数数据类型绑定的格式:在函数名之前加上(接收者 数据类型),即可将函数和某种数据类型绑定在一起(见定义部分的写法)

3)例子

给结构体添加一个方法,使该结构体除了可以保存数据,还具备说出自己名字和年龄的行为(有点像是类方法,但是其定义和实现是在结构体之外,结构体只具备表达数据结构的能力):

1
2
3
4
5
6
7
8
9
10
11
12
13
type Person struct{
    name string
    age int
}
 
func(p Person)say(){
    fmt.Println("my name is",p.name,"my age is",p.age)
}
 
func main(){
    per := Person{"lnj",33}
    per.say()
}

  

 

posted @   ShineLe  阅读(113)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
点击右上角即可分享
微信分享提示