golang函数一(定义、参数、返回值)-创新互联

对于GoLang函数的定义或者说理解:

创新互联公司服务紧随时代发展步伐,进行技术革新和技术进步,经过十多年的发展和积累,已经汇集了一批资深网站策划师、设计师、专业的网站实施团队以及高素质售后服务人员,并且完全形成了一套成熟的业务流程,能够完全依照客户要求对网站进行成都网站设计、网站制作、外贸营销网站建设、建设、维护、更新和改版,实现客户网站对外宣传展示的首要目的,并为客户企业品牌互联网化提供全面的解决方案。

函数是结构化编程中最小的模块单元,日常开发过程中,将复杂的算法过程分解为若干个小任务(代码块),使程序的结构性更清晰,程序可读性提升,易于后期维护和让别人读懂你的代码。

另外为了更好的重用你的代码,可以把重复性的任务抽象成一个函数。

Go语言中使用关键词func来定义一个函数,并且左花括号不能另起一行,比如:

func hello(){   //左花括号不能另起一行     println("hello") }

Go语言中定义和应用函数时,有如下需要注意的点:

 函数无须前置声明

 不支持命名嵌套定义,支持匿名嵌套

 函数只能判断是否为nil,不支持其它比较操作

 支持多返回值

 支持命名返回值

 支持返回局部变量指针

 支持匿名函数和闭包

func hello() {               //左括号不能另起一行 } func add(x,y int) (sum int){    //命名返回值     sum = x + y     return } func vals()(int,int){       //支持多返回值     return 2,3 } func a(){} func b(){} func add(x,y int) (*int){      //支持返回局部变量指针     sum := x + y     return &sum } func main(){     println(a==b)       //只能判断是否为nil,不支持其它比较操作     func hello() {      //不支持命名嵌套定义         println("hello")     } }

具备相同签名(参数和返回值)的函数才视为同一类型函数,比如:

func hello() {     fmt.Println("hello") } func say(f func()){      f() } func main(){     f := hello     say(f) }

参数:

Go语言中给函数传参时需要注意以下几点:

 不支持默认参数

 不支持命名实参

 参数视作为函数的局部变量

 必须按签名顺序传递指定类型和数量的实参

 相邻的同类型参数可以合并

 支持不定长变参,实质上是slice

func test(x,y int, s string, _ bool){   //相邻的同类型参数可以合并     return } func add(x ,y int) int {  //参数视作为函数的局部变量     x := 100            //no new variables on left side of :=     var y int = 200     //y redeclared in this block     return x +y } func sum(nums ...int) { //变参函数     total := 0     for _, num := range nums {         total += num     }     fmt.Println(total) } func main(){     //test(1,2,"s")       //not enough arguments in call to test     test(1,2,"s",false)     nums := []int{1, 2, 3}     sum(nums...) }

不管传递的是指针、引用还是其它类型参数,都是值拷贝传递的,区别在于拷贝的目标是目标对象还是拷贝指针而已。

在函数调用之前,编译器会为形参和返回值分配内存空间,并将实参拷贝到形参内存。比如:

func test1(x *int){     fmt.Printf("%p, %v\n",&x ,x) } func main(){     a := 0x100     p := &a     fmt.Printf("%p, %v\n", &p, p)     test1(p) } 输出: 0xc42002c020, 0xc42000a320 0xc42002c030, 0xc42000a320 从结构中看出, 实参和形参指向同一目标,但是传递的指针是被赋值了的

如果函数参数和返回值过多,可以将其封装成一个结构体类型,比如:

type serverOption struct{     addr    string     port int      path    string     timeout time.Duration } func newOption() * serverOption{     return &serverOption{         addr:"127.0.0.1",         port:8080,         path:"/var/www",         timeout: time.Second * 5,     }    } func (s *serverOption)server(){     println("run server") } func main(){     s := newOption()     s.port = 80     s.server()     for{} }

变参:

变参本质上是一个切片(slice),只能接收一到多个同类型参数,且必须放在参数列表尾部,比如:

func add(args ...int) int {   total := 0   for _, v := range args {     total += v   }   return total } func main() {   fmt.Println(add(1,2,3)) }

变参既然是切片,那是否可以直接传个切片或数组呢?

func test1(s string, a ...int){     fmt.Printf("%T, %v\n", a, a)    //[]int, [1 2 3 4] } {     a := [4]int{1,2,3,4}     test1("s", a)     //cannot use a (type [4]int) as type int in argument to test1                                                                                                                                    test1("s", a[:]     //cannot use a[:] (type []int) as type int in argument to test1     test1("s", a[:]...) //切片展开 }

变参既然是切片,那么参数复制的是切片的本身,并不包括底层的数组,因此可以修改原数据,但是可以copy底层数据,防止原数据被修改,比如:

func test1(a ...int){     for i := range a{         a[i] += 100     } } func main(){     a := [4]int{1,2,3,4}     // b := make([]int,0)     // copy(b,a[:])              // test1(b[:]...)     test1(a[:]...)     for i := range a{         fmt.Println(a[i])     } }

另外有需要云服务器可以了解下创新互联cdcxhl.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。


本文标题:golang函数一(定义、参数、返回值)-创新互联
文章链接:http://ybzwz.com/article/ipped.html