GO语言——函数介绍,与C++函数做对比

go语言中的函数定义

func functionName( [parameter list] ) [(returnName returnTypes)]) {
   
}

例如:

func add(a int, b int) (sum int){
    sum = a+b
    return
}

func add(a , b int) int{
    sum := a + b
    return sum
}

实际上这两种写法是等价的。第一种写法中,返回值是命了名的,这样在函数返回时可以直接返回而不用带结果。对应的C++代码为

int add(int a, int b)
{
    int sum = a + b;
    return sum;
}

返回值

另外go语言函数一次可以返回多个返回值,这点是C/C++做不到的,例如

func compare(a int, b int) (max int, min int){
    if a > b{
        max = a
        min = b
    }else{
        max = b
        min = a
    }
    return 
}

func main(){
    max, min := compare(10, 20)
    return
}

比较两个数,并返回大数和小数,在这种情况下返回值命名就有它的好处了。不然我们就要记住返回的顺序,容易出错。等价于

func compare(a int, b int) (int, int){
    if a > b{
        return a, b
    }else{
       return b, a
    }
}

传参

对于go语言来说一般都是传值,这点和C/C++一样,传递的是一个变量的副本,指针类型实际上也是一个变量。对于go语言来说和C语言一样只有指针类型,没有引用。例如

package main

import "fmt"

func pr(a *int) {
	fmt.Println("a = ", *a)
	*a = 20
}

func main() {
	a := 10
	pr(&a)
	fmt.Println("a = ", a)
}

输出
a = 10
a = 20

对应C++代码

#include <iostream>
using namespace std;

void pr(int* a)
{
    cout << "a = " << *a << endl;
    *a = 20
    return
}

int main()
{
    int a = 10;
    pr(&a);
    cout << "a = " << a << endl;
    reurn 0;
}

可以看得出目前为止,指针这种类型两种语言貌似没有什么区别。不过由于go语言是有垃圾回收的,所以当go的函数返回一个局部变量的指针是合法的,不像C/C++是非法的。go语言在传一些复杂的类型如map等可以看作的是传引用,原因很简单,因为go函数是传值的,所以只是把map的底层指针复制了,即C++中的浅拷贝。

匿名函数

package main

import "fmt"

func main() {
	var (
		a int = 10
		b int = 20
	)
	fmt.Println("a = ", a, " b = ", b)
	fun := func(p int) int {
		a = 20
		b = 30
		fmt.Println("p = ", p)
		return 0
	}
	fun(10)
	fmt.Println("a = ", a, " b = ", b)
}

输出
a =  10  b =  20
p =  10
a =  20  b =  30

等价于C++的

#include <iostream>
#include <functional>
using namespace std;


int main(int argc, char* argv[])
{
	int a = 10, b =20;
	cout << "a = " << a << " b = " << b << endl;
	auto fun = [&](int p)->int {
		a = 20;
		b = 30;
		cout << "p = " << p << endl;
		return 0;
	};

	fun(10);
	cout << "a = " << a << " b = " << b << endl;
	return 0;
}

可以看出,go会修改函数的外部变量,等价于c++指定传引用[&]

        除此之外go语言还有一个称为闭包的匿名函数方式,行为比较奇特。请看定义

package main

import "fmt"

func getfun() func() int {
	var i int
	return func() int {
		i++
		return i
	}
}

func main() {
	fun1 := getfun()
	fmt.Println("call fun1 ", fun1())
	fmt.Println("call fun1 ", fun1())
	fmt.Println("call fun1 ", fun1())

	fun2 := getfun()
	fmt.Println("call fun2 ", fun2())
	fmt.Println("call fun2 ", fun2())
	fmt.Println("call fun2 ", fun2())
}

输出
call fun1  1
call fun1  2
call fun1  3
call fun2  1
call fun2  2
call fun2  3

等价于C++中

#include <iostream>
#include <functional>
using namespace std;

function<int()> getfun()
{
	int& i = *(new int);
	i = 0;
	auto fun = [&]()->int {
		i++;
		return i;
	};
	return fun;
}

int main(int argc, char* argv[])
{
	auto fun1 = getfun();
	cout << "call fun1 " << fun1() << endl;
	cout << "call fun1 " << fun1() << endl;
	cout << "call fun1 " << fun1() << endl;

	auto fun2 = getfun();
	cout << "call fun2 " << fun2() << endl;
	cout << "call fun2 " << fun2() << endl;
	cout << "call fun2 " << fun2() << endl;
	return 0;
}

虽然行为上一致,但是可以看出两门语言有很多区别

区别一、go语言中的局部变量的生存周期可以在函数退出后继续存在。这里面就是i,C++为了模拟这个情况,我特意让这个i是new出来,并产生了严重的内存泄露

区别二、go语言会自动将局部变量初始化为0,但是C++,必须明确的赋值为0

不过目前还没有想到这种闭包的用途,希望大神指点。

另外就是函数作为方法,这有点像C++的类中的方法。等到介绍结构体时我再说明。

      最后,我学go语言才几天时间,只是粗粗的看了些语法,写这个系列的博客也是为了自己学习。所以可能会存在很多的错误。对这门语言的认识也不会有多深,还是烦请各路大神不吝赐教。谢谢。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值