设为首页 收藏本站
查看: 999|回复: 0

[经验分享] [golang note] 函数定义

[复制链接]

尚未签到

发表于 2018-9-20 07:41:42 | 显示全部楼层 |阅读模式
普通函数定义
   golang函数基本组成:关键字func函数名参数列表返回值函数体返回语句

· 语法如下
  

func 函数名(参数列表) (返回值列表) {  

// 函数体  
}
  


· 示例如下
  

package main  

  
import
"fmt"  
import
"errors"  

  
func
Add(a int, b int) (ret int, err error) {  

if a < 0 || b < 0 { // 假定只支持两个非负数字的加法  
err = errors.New("Should be non-negative numbers!")
  
return
  
}
  
    return a + b, nil
  
}
  

  
func main() {
  
fmt.Println(Add(-1, 1))
  
fmt.Println(Add(10, 1))
  
}
  


· 注意事项
  ▪ golang函数支持多返回值,返回时没有被明确赋值的返回值将被设置为默认值
  ▪ golang函数返回值可以命名,但不是强制规则,给返回值命名可以让让代码更清晰,可读性更强,同时也可以用于文档。
  ▪ golang函数定义中左花括号的位置被强制规范,如果左花括号放置不规范,golang编译器报告编译错误:syntax error: unexpected semicolon or newline before {。
  ▪ golang函数定义中如果参数列表中若干个相邻参数的类型相同,则可以在参数列表中省略前面的变量类型声明。
  

func Add(a, b int) (ret int, err error) {  

// 函数体  
}
  

  ▪ golang函数定义中如果返回值列表中若干个相邻返回值的类型相同,则可以在返回值列表中省略前面的变量类型声明。
  

func Add(a, b int) (ret, err int) {  
    // 函数体
  
}
  

  ▪ golang函数定义中如果返回值只有一个,那么返回值列表可以简略表示。
  

func Add(a, b int) int {  
    // 函数体
  
}
  


固定类型的不定参数函数定义

· 语法如下
  

func 函数名(args ...Type) (返回值列表) {  
    // 函数体
  
}
  

   形如args ...Type的用法只能作为函数的参数类型,并且必须是最后一个参数
   形如args ...Type的用法是一个语法糖(syntactic sugar),即对语言功能没有影响,但可以增加程序的可读性。
   形如args ...Type的用法从内部实现上说,其本质上是一个数组切片,即[]type,因此可以用for循环来获得每个传入的参数。

· 示例如下
  

package main  

  
import
"fmt"  

  
func
myfunc(prefix string, args ...int) {  
fmt.Print(prefix,
" : ")  

  

for _, arg :=range args {  
fmt.Print(arg,
" ")  
}
  

  
fmt.Println()
  
}
  

  
func main() {
  
myfunc(
"data1", 1, 2, 3, 4)  
myfunc(
"data2", 4, 3, 2, 1, 0)  
}
  


· 不定参数函数互相调用

▶ 原样传递

▪ 语法如下
  

func myfunc1(args ...Type) {  

// 函数体  
}
  

  
func myfunc2(args ...Type) {
  
...
  
myfunc1(args...)
  
...
  
}
  


▪ 示例如下
  

package main  

  
import
"fmt"  

  
func
myfunc1(args ...int) {  
fmt.Println(
"myfunc1() invoked")  

  

for _, arg :=range args {  
fmt.Print(arg,
" ")  
}
  

  
fmt.Println()
  
}
  

  
func myfunc2(args ...
int) {  
fmt.Println(
"myfunc2() invoked")  
myfunc1(args...)
  
}
  

  
func main() {
  
myfunc2(
1, 2, 3, 4)  
}
  


▶ 片段传递

▪ 语法如下
  

func myfunc1(args ...Type) {  

// 函数体  
}
  

  
func myfunc2(args ...Type) {
  
...
  
myfunc1(args[m:n]...)
  
...
  
}
  


▪ 示例如下
  

package main  

  
import
"fmt"  

  
func
myfunc1(args ...int) {  
fmt.Println(
"myfunc1() invoked")  

  

for _, arg :=range args {  
fmt.Print(arg,
" ")  
}
  

  
fmt.Println()
  
}
  

  
func myfunc2(args ...
int) {  
fmt.Println(
"myfunc2() invoked")  
myfunc1(args[
2:3]...)  
}
  

  
func main() {
  
myfunc2(
1, 2, 3, 4)  
}
  


任意类型的不定参数函数定义

· 语法如下
  

func 函数名(args ...interface{}) (返回值列表) {  

// 函数体  
}
  

   形如args ...interface{}的用法只能作为函数的参数类型,并且必须是最后一个参数。

· 示例如下
  

package main  

  
import
"fmt"  

  
func
MyPrintf(info string, args ...interface{}) {  
fmt.Println(info)
  

for _, arg :=range args {  

switch arg.(type) {  

case int:  
fmt.Println(arg,
"is an int value.")  

case string:  
fmt.Println(arg,
"is a string value.")  

case int64:  
fmt.Println(arg,
"is an int64 value.")  

default:  
fmt.Println(arg,
"is an unknown type.")  
}
  
}
  
}
  

  
func main() {
  

var v1 int = 1  
var v2 int64 = 234
  
var v3 string = "hello"
  
var v4 float32 = 1.234
  

  
MyPrintf("MyPrintf", v1, v2, v3, v4)
  
}
  


匿名函数与闭包

· 匿名函数
   匿名函数是指不需要定义函数名的一种函数实现方式,函数可以像普通变量一样被传递或使用。

▶ 匿名函数赋值给变量

▪ 语法如下
  

f :=func(参数列表) (返回值列表) {  

// 函数体  
}
  


▪ 示例如下
  

package main  

  
import
"fmt"  

  
func
main() {  
f :
= func(x, y int) int {  

return x + y  
}
  

  
fmt.Println(
"Result =", f(1, 2))  
}
  


▶ 匿名函数直接调用

▪ 语法如下
   匿名函数定义的花括号后直接跟参数列表表示函数调用。
  

func(参数列表) (返回值列表) {  

// 函数体  
} (参数列表)
  


▪ 示例如下
  

package main  

  
import
"fmt"  

  
func
main() {  
fmt.Println(
"Result =",  
func(x, y
int) int {  

return x + y  
}(
1, 2))  
}
  


· 闭包

▶ 闭包概念
   闭包是可以包含自由变量(未绑定到特定对象)的代码块。这些自由变量不在该代码块内或任何全局上下文中定义,而是在定义代码块的环境中定义。要执行的代码块为自由变量提供绑定的计算环境,即作用域。
   自由变量包含在代码块中,这些自由变量以及其引用的对象将不被释放。闭包的实现确保只要闭包还被使用,那么被闭包引用的变量会一直存在。
   golang的匿名函数就是一个闭包,闭包函数可以存储到变量中作为参数传递给其他函数,最重要的是能够被函数动态创建和返回。
   自由变量的值将被隔离,在闭包外不可修改,只有内部匿名函数才能访问,而无法通过其他途径访问,因此确保了变量的安全性。

▶ 闭包使用

▪ 语法如下
  

c :=func() func(参数类型列表) 返回值类型列表 {  

// 自由变量定义  ...
  
returnfunc(参数列表) 返回值列表 {
  
// 函数定义
  
}
  
}()
  


▪ 示例如下
  

package main  

  
import (
  

"fmt"  
)
  

  
func main() {
  
result :
= 0  

  
// 闭包定义
  
c := func() func(int) int {
  
i := 0
  
return func(j int) int {
  
i += 10
  
fmt.Printf("i = %d, j = %d\n", i, j)
  
return i + j
  
}
  
}()
  

  
result = c(10)
  
fmt.Printf("i + j= %d\n", result)
  

  
result = c(20)
  
fmt.Printf("i + j= %d\n", result)
  

  
result = c(30)
  
fmt.Printf("i + j= %d\n", result)
  
}
  


main函数
   main函数是golang可执行程序的执行起点。
   main函数不能带有参数,命令行传入的参数在os.Args变量中保存。
  

package main  

  
import (
  

"fmt"  
"os"
  
)
  

  
func main() {
  

for i, v :=range os.Args {  
fmt.Printf(
"os.Args[%d] = %s\n", i, v)  
}
  
}
  




运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-597898-1-1.html 上篇帖子: [golang]内存不断增长bytes.makeSlice 下篇帖子: 【GoLang】golang context channel 详解
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表