关于思否技术征文:Go-函数注意事项

39次阅读

共计 3044 个字符,预计需要花费 8 分钟才能阅读完成。

细节汇总

  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
  11. 反对对函数返回值命名(能够不受返回值程序限度
  12. 应用 _ 下划线标识符,疏忽返回值。(占位符
  13. 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

    可变参数

    根本语法

  2. 反对零到多个参数

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

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

酷爱前端开发,也喜爱专研各种跟本职工作关系不大的技术,技术、产品趣味宽泛且浓重。本号次要致力于分享集体经验总结,心愿能够给一小部分人一些渺小帮忙。

心愿能和大家一起致力营造一个良好的学习气氛,为了集体和家庭、为了我国的互联网物联网技术、数字化转型、数字经济倒退做一点点奉献。数风流人物还看中国、看今朝、看你我。

本文参加了思否技术征文,欢送正在浏览的你也退出。

正文完
 0