【函数定义】

        func function_name([parameter1 type,parameter2 type])[return_value1 return_type1,return_value2 return_type2,...]{
            //TODO
        }
        func : 函数有func开始声明
        function_name : 函数名称,函数名和参数列表一起构成函数签名
        parameter_list : 参数列表,参数就像是一个占位符,当函数被调用时,你可以将值船体给参数,这个值被称为实际参数。
                        参数列表指定的是参数类型、顺序、及参数个数。参数是可选的,也就是说函数也可以不包含参数。
        return_types:返回类型,函数返回一列值。return_types 是该列值的数据类型。有些功能不需要返回值,这种情况下 return_types 不是必须的。
        函数体:函数定义的代码集合
    备注:除了main() init()函数外,其他的函数尊循以上格式

【函数类型】

  Go中有三种类型:
  • 普通的带有名字的函数
  • 匿名函数或者lambda函数
  • 方法(Method)(与结构体有关)
  • 特殊的有main(),init()函数

【函数的书写格式及调用说明】

  简单举例,如果没有参数、参数类型、返回值,返回类型等,可以省略  
  func functionName(){  // 大括号必须和函数声明同行
      // TODO
  }
  使用方式:调用
  package.FunctionName(arg1,arg2...)  // 包中的函数若想被外部调用,函数必须首字母大写
  使用方式:声明
  type binOp func(int,int) int
 
     调用说明:
  • 包中的函数若想被外部调用,函数必须首字母大写
  • Go中函数重载是不被允许的,会导致一个编译错误
  • 函数也可以作为一个函数类型来声明
  • 函数可以赋值给变量
  • 一个变量不能被赋值不同的函数,就像一个变量不能被声明多次一样的道理
  • Go没有泛型的概念
  • 函数不能在其他函数里嵌套声明,也就是说不能再函数体内声明(创造)函数,一般在函数体内使用匿名函数来完成这个
  • 函数值之间可以互相比较,如果它们引用的是相同的函数或者都是nil的话,则认为它们是相同的

【函数的参数】

    按值传递:就是形参
    引用传递:按变量的内存地址传递,即取变量的内存地址,可以说就是指针,&变量,例如&a
    在函数调用中:切片(slice)字典(map)接口(interface)通道(channel)这样的引用类型都是默认使用引用传递(没有显式的指出指针)
    
    备注:在函数返回值多的时候,可以使用切片(返回值具有相同类型)或者结构体(返回值具有不同类型)

【函数的返回值】

    命名返回值:作为结果形参(result parameters)被初始化为响应类型的零值,当需要返回的时候,我们只需要一条简单的return。命名返回值 需要用()括起来,即使只有一个 func funcName()(ret int){}
    非命名返回值:作为结果形参,需要返回的时候,return 后面需要跟返回的内容,多个非命名返回值 需要用括号()括起来,一个的时候不需要括起来,func funcName()(int,int)
 // 举例
package main import "fmt" var num int = 10
var numx2, numx3 int func main(){
numx2, numx3 = getX2AndX3(num)
PrintValues()
numx2, numx3 = getX2AndX3_2(num)
PrintValues()
} func PrintValues(){
fmt.Printf("num = %d, 2x num = %d, 3x num = %d\n", num, numx2, numx3)
} func getX2AndX3(input int)(int, int){ // 定义了函数返回的参数个数及参数类型
return 2 * intput, 3 * input
}
// 使用了命名返回值
func getX2AndX3_2(input int)(x2 int, x3 int){
x2 = 2 * input
x3 = 3 * input
// return x2, x3
return // 因为使用了命名返回值,所以return的时候,就按照命名返回值的变量返回。
备注:尽量使用命名返回值,使代码更加清晰,提高可读性
 

【传递变长参数】

     如果函数的最后一个参数是采用...type(type表示数据类型)的形式,那么这个函数就可以处理一个变长的参数,这个长度可以为0,这样的函数叫变长函数
  // 结构
  func myFunc(a,b,arg ...int){}
  // 事例及调用
  func Greeting(prefix string, who ...string)
  Greeting("Hello:","Joe","Anna","Robot")  // 变量who的值为[]string{"Joe","Anna","Robot"}
 
  在Greeting函数中,变量who的值为[]string{"Joe","Anna","Robot"}
  如果参数被存储在一个数组中arr,则可以使用arr...的形式传递参数调用 函数
 package main

 import "fmt"

 func main(){
x := min(1,3,2,0)
fmt.Printf("The minimum is: %d\n", x)
arr := []int{7,9,3,5,1}
x = min(arr...)
fmt.Printf("The minimum in array arr is:%d",x)
} func min(a ...int)int{
if len(a) == 0 {
return 0
}
min := a[0]
for _, v := range a{
if v < min {
min = v
}
}
return min
}
 
    如果变长的参数类型不相同怎么办?
        使用结构体
  在这个结构体中存储任意类型的参数
  type Options struct{
      par1 type1,
      par2 type2,
      par3 type3,
  }
  // 使用
  FuncName(a,b,Option{par1:val1,par2:val2})
  使用空接口:该方案不仅可以用于长度未知的参数,可以用于不确定类型的参数,一般使用for-range循环,switch结构对每个参数的类型进行判断
  func typecheck(...,...,values ...interface{}){
      for _, value := range values{
          switch v := value.(type){
              case int:...
              case float:...
              case string:...
              case bool:...
              default:...
          }
      }
  }
 
        

【defer和追踪】

  关键字defer允许我们推迟到函数返回之前一刻,才执行被defer修饰的某个语句或者函数。类似其他语言中的finally
 // 示例
package main import "fmt" func main(){
funciton1()
} func function1(){
fmt.Printf("In function1 at the top\n")
defer function2()
fmt.Printf("In function1 at the bottom\n")
} func function2(){
fmt.Printf("function2:Defered until the end of the calling function!")
} // 输出
In function1 at the top
In function1 at the bottom
function2:Defered until the end of the calling function
    使用场景:
        关闭文件流,defer file.Close()
        解锁一个加锁的资源  defer mu.Unclock()
        打印最终报告 defer printFooter()
        关闭数据库链接 defer disconnectFromDB()
 
 

【递归函数】

  演示斐波那契和阶乘
 package main

 import "fmt"

 func main(){
result := 0
for i := 0; i<=10;i++{
result = fibonacci(i)
fmt.Printf(result)
}
} func fibonacci(n int)(ret int){
if n < 2{
ret = 1
}else{
ret = fibonacci(n-1)+fibonacci(n-2)
}
return
}
 package main

 import "fmt"

 func main(){
var n int = 30
result := factorial(n)
fmt.Printf("n的阶乘是:%d",result) } func factorial(n int)(res int){
if n > 0{
res = n * factorial(n-1)
}else{
res = 1
}
return
}
 
 

【闭包的应用:将函数作为返回值】

    代码来展示Go中如何将函数作为返回值
 package main

 import "fmt"

 func main(){
func_param1 := add1(2)
fmt.Println(func_param1(3))
func_param2 := add2()
fmt.Println(func_param2(3))
} func add1(n int) func(a int) int{
return func(a int) int{
return a + n
}
} func add2() func(a int) int{
return func(a int) int{
return a + 2
}
} // 输出结果
5
5
    
    作为闭包的应用
 package main

 import "fmt"

 func main(){
var f = add()
fmt.Println(f(10))
fmt.Println(f(20))
fmt.Println(f(30))
} func add() func(a int) int{
var x int
return func(a int) int{
x += a
return x
}
}
// 输出结果
10
30
60
    这个程序说明变量x的值在三次调用函数类型变量f()时,都被操作了累积了
    
    下面使用闭包来实现斐波那契数列的程序,放弃递归的方法
 package main

 import "fmt"

 func main(){

     var i int
f := fibonacci()
for i = 0; i < 10; i++{
fmt.Println(f(i))
}
} func fibonacci() func(a int) int{
var res int
var last int
var last_last int
return func(a int) int{
if a < 2{
res = a
}else{
res = last_last + last
}
last_last = last
last = res
return res
}
}
 【学习参考处:https://github.com/Unknwon/the-way-to-go_ZH_CN/blob/master/eBook/directory.md】
 
 
 
 
 
 
 
 
 
 

Go笔记-函数的更多相关文章

  1. Python编程从入门到实践笔记——函数

    Python编程从入门到实践笔记——函数 #coding=gbk #Python编程从入门到实践笔记——函数 #8.1定义函数 def 函数名(形参): # [缩进]注释+函数体 #1.向函数传递信息 ...

  2. 《python基础教程(第二版)》学习笔记 函数(第6章)

    <python基础教程(第二版)>学习笔记 函数(第6章) 创建函数:def function_name(params):  block  return values 记录函数:def f ...

  3. <数据结构与算法分析>读书笔记--函数对象

    关于函数对象,百度百科对它是这样定义的: 重载函数调用操作符的类,其对象常称为函数对象(function object),即它们是行为类似函数的对象.又称仿函数. 听起来确实很难懂,通过搜索我找到一篇 ...

  4. swift swift学习笔记--函数和闭包

    使用 func来声明一个函数.通过在名字之后在圆括号内添加一系列参数来调用这个方法.使用 ->来分隔形式参数名字类型和函数返回的类型 func greet(person: String, day ...

  5. 《JS语言精粹》学习笔记 函数部分の闭包

    要理解闭包,首先要理解变量作用域,变量的作用域就两种,全局变量和局部变量,函数内部可以直接读取全局变量,函数外部无法读取函数内部的局部变量. 闭包定义:能读取函数内部局部变量的函数就是闭包,而只有函数 ...

  6. Python学习笔记——函数

    1.标准类型内建函数 <1>type() —— 返回对象的类型 <2>cmp() —— 比较两个对象,返回两个对象的ASCII码的差 <3>str().repr() ...

  7. golang笔记——函数与方法

    如果你遇到没有函数体的函数声明,表示该函数不是以Go实现的. package math func Sin(x float64) float //implemented in assembly lang ...

  8. JavaScript笔记:函数

    函数是定义一次但却可以调用或执行任意多次的代码块. 一.函数定义 javascript中的函数使用function关键字来定义,常用的函数定义分为三种形式: 声明式函数定义 function sum( ...

  9. JavaScript学习笔记-函数

    函数的两种创建方式:函数定义表达式.函数声明语句 编译时,函数声明语句创建的函数会‘被提前’至外部函数的作用域顶部,在该作用域内可以被随意调用: 而函数表达式创建的函数,要调用它必须赋值给一个变量,编 ...

  10. JavaScript学习笔记-函数实例

    函数实例 var p = { a:15, b:'5', f1:function(){ var self = this; console.log(self.a+self.b); f2(); functi ...

随机推荐

  1. poj 2758 && BZOJ 2258 Checking the Text 文本校对

    Description   为了给Wind买生日礼物,Jiajia不得不找了一份检查文本的工作.这份工作很无聊:给你一段文本 要求比对从文本中某两个位置开始能匹配的最大长度是多少.但比无聊更糟糕的是, ...

  2. 2017"百度之星"程序设计大赛 - 复赛1003&&HDU 6146 Pokémon GO【数学,递推,dp】

    Pokémon GO Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  3. Codeforces Round #442 (Div. 2)

    A. Alex and broken contest time limit per test 2 seconds memory limit per test 256 megabytes input s ...

  4. 了解 Python 语言中的时间处理

    python 语言对于时间的处理继承了 C语言的传统,时间值是以秒为单位的浮点数,记录的是从1970年1月1日零点到现在的秒数,这个秒数可以转换成我们日常可阅读形式的日期和时间:我们下面首先来看一下p ...

  5. Qt 共享库(动态链接库)和静态链接库的创建及调用

    前言: 编译器 Qt Creator, 系统环境 win7 64 位 1.创建共享库: 新建文件或项目->选择 Library 和 c++ 库->选择共享库->下一步(工程名为 sh ...

  6. 程序员听到bug后的N种反应,太形象了

    程序员的世界里,不止有代码,还有bug,bug,bug 当出现bug时,程序员们的反应是怎样的呢?

  7. Video Target Tracking Based on Online Learning—深度学习在目标跟踪中的应用

    摘要 近年来,深度学习方法在物体跟踪领域有不少成功应用,并逐渐在性能上超越传统方法.本文先对现有基于深度学习的目标跟踪算法进行了分类梳理,后续会分篇对各个算法进行详细描述. 看上方给出的3张图片,它们 ...

  8. html5只需要<!DOCTYPE HTML>的原因

    首先我们先了解两个东西: SGML:标准通用标记语言(以下简称"通用标言"),是一种定义电子文档结构和描述其内容的国际标准语言:[1]  通用标言为语法置标提供了异常强大的工具,同 ...

  9. 空数组在以下三种遍历中均不可更改:forEach、map和for...in

    首先,我们要知道对于forEach.map和for...in三种遍历,在不是空数组的情况下,要想实现更改原数组的方法,代码如下: var list = [1,2,3,4]; var list1 = [ ...

  10. PHP和Python如何选择?或许可以考虑这三个问题

    撤稿纠错 文/黄小天.李亚洲 (选自Hackernoon 机器之心编译) 2017 年可谓是网页应用与 API 之年,开发者不用每次重新发明轮子,而是利用脚手架和第三方库就能确保项目在几天内实时部署. ...