从入职开始学习Go也有2周了吧,看书比较慢,加上平时使用,对于Golang只能说是有了一个初步的了解。一边翻书,一边简单的总结一点基础的东西。写着写着感觉就变成了一个C++11和Golang的比较。
变量
1、:= 初始化
相对于C,go提供的:=可以推导表达式的类型还是很方便的,如同C11里提供的 auto 类型。
但是也有个坑在这里。:= 操作相当于生命了一个变量,不能用于给已经存在的变量进行赋值,这样会报错。而且:=不能用于声明全局变量。
2、多重赋值
多重赋值实在是方便,比如swap直接写 a,b = b,a就可以。但是因为有了多重赋值,C/C++的 , 逗号表达式被取消了。我个人觉得是因为这个原因,因为这样写就会有歧义:
a,b = 4,c如果有,逗号表达式, 就会有歧义:到底是多重赋值还是声明语句呢?
3、iota 与 const 枚举
- 我自己把这俩划分到一起了,因为iota实在是让我感到迷惑。。。这个iota其实跟true false 一样是go的预定义常量,只不过iota可以被编译器修改。iota我个人觉得就是一个const枚举中的行号。iota有些限制只能在 const 里面使用
- 是 const 里面的行数索引器
- 每个 const 里面,iota 都从 0 开始。
const( A = iota B C )
这个const(
)又是一个枚举一样的东西,每个变量都有一个右值,因此iota可以被用于推断行号...上例中,A是1,B是2,C是3,因为iota从0开始计算。
4、bool
bool终于不能够再被随意的赋值了。也就是说你不能让一个bool等于1或者0。这应该是一个更加严谨的决定。虽然会有一些麻烦。
5、~ 变成了 ^
golang规定,取反运算符是 ^ 。。。
6、数组 与 切片slice
数组分配后不可修改长度,这与C中的内置类型数组相似。因此也会需求类似vector的容器。好在有slice。
其实slice跟vector真的很相似。都是基于内置数组而封装出的可变数组,都有capcity和length,这种allocate之后再new的方式让人更容易控制分配效率和性能。
我不知道slice是不是如同vector,每次size==capcity之后都成倍扩大capcity。但是这个功能真的提高了很多效率,尤其再这样一个有GC的语言中,复用显得更加重要。
7、map的查找
golang的map查找非常方便,不像C++会有at函数和[]运算符的区别。
value,ok := map[key] if ok{ //DO }
golang中的每次map访问都会返回2个值,一个是key对应的value,另一个是是否含有这个key对应的value,因此避免了复杂的判断步骤。
8、匿名函数 与函数闭包
想了很久决定把这两个特性放在一个题目下
C11中引入了匿名函数lambda,使用[]捕获列表的方式获得上下文环境,其实就是创建了一个重载了()的匿名的可调用类,lambda就是这样一个类的一个实例。然后又说到了闭包,c11中的lambda其实也算是一种闭包吧我觉得,有人曾经给我类比函数指针来讲解闭包我觉得这是个错误的例子
//C++:举例子,写了一个重载了()的类class F class F { private: <pre name="code" class="cpp"> <span style="font-family: Arial,sans-serif;">double a = 1.0;</span>
<span style="font-family: Arial,sans-serif;">public:</span>
<span style="font-family: Arial,sans-serif;">double operator ()(double x,double y) const;/</span>};double F::operator ()(double x,double y) const{
<span style="font-family: Arial,sans-serif;">return (x+a)*y;</span>}int main(){
<span style="font-family: Arial,sans-serif;">F f;</span>
std::cout<span style="font-family: Arial,sans-serif;"><<f(1.5,2.2)<<std::endl;</span>
<span style="font-family: Arial,sans-serif;">return 0;</span>}
go中的闭包也是如此(demo改了N次终于觉得符合我的想法啦!)
//golang中的闭包与匿名函数 func main() { <pre name="code" class="cpp"> <span style="font-family: Arial,sans-serif;">var a float64 = 1.0</span>f := func(x,y float64) float64 { return (x + a) * y } fmt.Println(f(1.5,2.2))} 再来对比一下C++中的lambda
//C++中的lambda int main() { double a = 1.0; auto f = [&a](double x,double y) ->return double { return (x + a) * y }; std::cout << f(1.5,2.2) << std::endl; }
区别并不大,我也是做一个比较,如果不知这样也希望指教。打心里说,我更喜欢C++的lambda一点。
9、panic() recover() 与 defer
把这三个放在一起也是没想好能不能这么总结