Go | 函数注意事项

细节汇总

  1. 函数的形参列表可以是多个,返回值列表也可以是多个
  2. 形参列表和返回值列表的数据类型,可以是值类型、也可以是引用类型
  3. 函数的命名遵循标识符命名规范,首字母不能是数字,首字母大写表示该函数可以被本包文件和其它文件使用,类似public;首字母小写只能被本包文件使用,类似private。
  4. 函数中的变量是局部的,外部不能访问。作用域
  5. 基本数据类型和数组都是值传递的,即进行值拷贝。在函数内修改,不会影响到原来的值,
  6. 如果希望函数内的变量能够修改函数外的变量,可以传入变量的地址(&),函数内以指针的方式操作变量,从效果上看类似引用
  7. Go函数不支持函数重载。
  8. 在Go中,函数也是一种数据类型,可以赋值给一个变量,则该变量是一个函数类型的变量,通过该变量可以对函数调用。
  9. 函数既然是一种数据类型,因此在Go中,函数也可以作为形参,并且调用。(回调函数
  10. 为了简化数据类型定义,Go支持自定义数据类型
  • 语法: type 自定数据类型名 数据类型 (相当于一个别名)

  • 案例: type myInt int 这时,myInt就等价于int来使用了

  • type mySum func(int, int) int 这时,mySum就等价于func(int, int) int

  1. 支持对函数返回值命名(可以不受返回值顺序限制
  2. 使用 _ 下划线标识符,忽略返回值。(占位符
  3. Go支持可变参数

值传递和指针传递

func test(n1 int) {
    n1 = n1 + 10
    fmt.Println("test n1=", n1)
}

// 指针类型接收处理
func test02(n2 *int) {
    *n2 = *n2 + 10
    fmt.Println("test02 n2=", *n2)
}

func main() {
    n1 := 20
    n2 := 2
    test(n1) // 值类型
    test02(&n2) // 指针类型
    fmt.Println("main n1=", n1)
    fmt.Println("main n2=", n2)
}

什么是重载

重载: 函数名相同,但是形参不同或者数据类型不同的情况。

Golang语言中是不支持传统的函数重载的,fn redeclared in this block

Golang语言是支持可变参数的,空接口的形式

函数类型的变量

类型: func(int, int) int

func getSum(n1 int, n2 int) int {
    return n1 + n2
}
func getSums(n1 int, n2 int, n3 int) int {
    return n1 + n2 + n3
}

// main 函数
sumFn := getSum
res := sumFn(10, 20)
fmt.Printf("%T %v\n", res, res) // int 30
fmt.Printf("%T \n", sumFn) // func(int, int) int

sumsFn := getSums
result := sumsFn(10, 20, 30)
fmt.Printf("result : %T %v\n", result, result) // result : int 60
fmt.Printf("sumsFn类型:%T \n", sumFn) // sumsFn类型:func(int, int) int

函数作为形参传入

func getSum(n1 int, n2 int) int {
    return n1 + n2
}
func testFn(fnVar func(int, int) int, num1 int, num2 int) int {
    return fnVar(num1, num2) // 调用传入的函数,并返回值
}

// 函数类型形参
sumFn := getSum
total := testFn(sumFn, 1, 2)
fmt.Println("total=", total) // 3

自定义数据类型

  1. 自定义函数数据类型, 相当于起了一个别名
type mySum func(int, int) int

func testFn(fnVar mySum, num1 int, num2 int) int {
    return fnVar(num1, num2)
}

// func testFn(fnVar func(int, int) int, num1 int, num2 int) int {
//  return fnVar(num1, num2)
// }
  1. 自定义数据类型
// main函数下
type myInt int
var num1 myInt = 2
// var num2 int = num1 // 这样是报错的, myInt和int并不等价
var num2 int = int(num1) // 显式类型转换
fmt.Printf("num1的类型:%T 值:%v \n", num1, num1) // num1的类型:main.myInt 值:2
fmt.Printf("num2的类型:%T 值:%v \n", num2, num2) // num2的类型:int 值:2
  1. 定义的类型: 包名.类型名,如:utils.myInt
// 以下是utils包
package utils

import "fmt"

func TestFn() string {
    fmt.Println("TestFn 函数被调用")
    type myInt int
    var n myInt = 10
    fmt.Printf("n的类型:%T 值:%v", n, n) // n的类型:utils.myInt 值:10
    return "hahaha"
}

返回值命名

func sumSub(n1 int, n2 int) (sum int, sub int) {
    // 这里不需要声明sum, sub变量了,也不用在return时写
    sum = n1 + n2
    sub = n1 - n2
    return
}

// main函数
sum, sub := sumSub(9, 8)
fmt.Println("sum=", sum, "sub=", sub) // sum= 17 sub= 1

可变参数

基本语法

  1. 支持零到多个参数

func sum(args... int) {}

  1. 支持1到多个参数

func sum(n1 int, args... int) {}

args:就是一个承接的变量名,可以自定义,如:func sum(n1 int, **vars**... int) {}

说明:

  • args是slice切片,通过args[index]可以访问到各个值
  • args必须放到形参列表的最后面

参数个数可变

func sumV2(n1 int, args ...int) int {
    sum := n1
    fmt.Printf("args类型是:%T\n", args) // args类型是:[]int
    // 遍历args切片
    for i := 0; i < len(args); i++ {
        sum += args[i]
    }
    return sum
}

// main函数
// 参数可变
total02 := sumV2(1, 2, 3, 4)
fmt.Println("total02=", total02) // total02= 10

总结练习

交换变量a, b的值

package main

import "fmt"

func swap(n1 *int, n2 *int) {
    *n1 = *n1 + *n2
    *n2 = *n1 - *n2 // *n1
    *n1 = *n1 - *n2 // *n2
}

func main() {
    a := 12
    b := 20
    swap(&a, &b)
    fmt.Println("a = ", a, "b = ", b)
}

我是 甜点cc

微信公众号:【看见另一种可能】

热爱前端开发,也喜欢专研各种跟本职工作关系不大的技术,技术、产品兴趣广泛且浓厚。本号主要致力于分享个人经验总结,希望可以给一小部分人一些微小帮助。

希望能和大家一起努力营造一个良好的学习氛围,为了个人和家庭、为了我国的互联网物联网技术、数字化转型、数字经济发展做一点点贡献。数风流人物还看中国、看今朝、看你我。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 161,601评论 4 369
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 68,367评论 1 305
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 111,249评论 0 254
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,539评论 0 217
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,967评论 3 295
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,929评论 1 224
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,098评论 2 317
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,825评论 0 207
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,609评论 1 249
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,796评论 2 253
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,282评论 1 265
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,603评论 3 261
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,277评论 3 242
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,159评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,959评论 0 201
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 36,079评论 2 285
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,874评论 2 277

推荐阅读更多精彩内容