Golang部份特性的C++对比实现
来源:互联网 发布:java终止线程 编辑:程序博客网 时间:2024/05/18 01:49
今天看到一篇文章<<C++ 逐渐 Python 化>>, 我个人是认为这个说法是不成立的,但这里面的一些特性对比引起了我的兴趣。
我想尝试下,Go语言所带的一些东西,在C++11中是如何做的,应当很有意思。所以刷刷刷,就有了下面的东西。
目录:
字符串字面值
变量初始化
lambda
值顺序递增
多值赋值及函数返回多值
map查找
可变参数
回调函数
泛型
数组和切片
字面值
这个东西在两种语言中都有比较好的解决方式.Go语言用" ` "符号,C++使用R(" )"这种方式。可以省掉不少转义符的输入。
Golang
path := `c:\a\b\c\GG再也不用烦转义符了`mulln := `"(C++/Golang aa'aaa\Cplusplus/gogogo author"xiongchuanliang`fmt.Println(path)fmt.Println(mulln)C++
string path = R"(c:\a\b\c\GG再也不用烦转义符了)";cout << "单行:" << path.c_str() << endl;string muln = R"(C++/Golang aa'aaa\Cplusplus/gogogo author"xiongchuanliang)";cout << "多行:" << muln.c_str() << endl;
变量初始化
现在开发语言的初始化都差不多,都能很方便的定义时初始化,循环也是如下面中的C++ for循环和Go语言中的"for : rang"
形式基本一样。 另外C++的auto,Go语言中的":=",都能省代码的好东西。不过要多提一句,Go语言支持多重赋值,并且变量都
是默认就已初始化好。同时,Go语言也支持指针,但它的指针要安全得多。
Golang
var k intfmt.Println(k)mArr := []int{ 1, 2, 3}var mMap = map[string]int {"a":1,"b":2}fmt.Printf("array:%v\nmap:%v \n",mArr,mMap)i := 10 pi := &i //*ippi := &pi //**intfmt.Println(i,*pi,**ppi)//结果:0array:[1 2 3]map:map[a:1 b:2]10 10 10
C++
int mArr[] = { 1, 2, 3 };auto mList = vector < int > {1, 2, 3, 4};auto mMap = map < int, string > {{1, "aa"}, { 2, "bb" }};cout << "vector: ";for (const int& x : mList)cout << x << " ";cout << endl;cout << "map: ";for (const auto& mp : mMap)cout << mp.first << " " << (mp.second).c_str();cout << endl;
lambda
lambda这东西在C++11中可是重点推荐的特性,非常的强大。Go语言自然也有,但对于匿名函数中函数外部变量的处理
并没有C++那么多种。 像C++分了四类:
[a,&b] a变量以值的方式呗捕获,b以引用的方式被捕获。
[this] 以值的方式捕获 this 指针。
[&] 以引用的方式捕获所有的外部自动变量。
[=] 以值的方式捕获所有的外部自动变量。
[] 不捕获外部的任何变量。
而Go语言默认就相当于"[=]",即,捕获可见范围内所有的外部变量。
Golang
mArr := []int{ 1, 2, 3}fun := func(i,v int){fmt.Printf("idx:%d value:%d \n",i,v)}for idx,val := range mArr{fun(idx,val)}
C++
int arr[] = { 1, 2, 3 };for_each(begin(arr), end(arr), [](int n){cout << n << endl; });auto func = [](int n){cout << n << endl; };for_each(begin(arr), end(arr), func);
值顺序递增(iota)
iota这个小东西很有特点,两种语言都支持且都是让数据顺序递增,从功能上看C++的iota似乎更强大灵活些。 但有意思的是,
似乎在Go语言中,iota的使用频率要高得多,被大量的用于像const定义之类的地方,有意思。
Golang
const (Red = iotaGreenBlue)fmt.Println("Red:",Red," Gree:",Green," Blue:",Blue);
C++
int d[5] = { 0 };std::iota(d, d + 5, 10);cout << "iota_demo(): old : d[5] = { 0 } "<< endl;cout << "iota_demo(): iota: d[5] = { ";for each (int var in d){cout << var <<" ";}cout <<"} "<< endl;char e[5] = { 'a' };char f[5] = { 0 };copy_n(e, 5, f);cout << "iota_demo(): old : e[5] = { 'a' } " << endl;cout << "iota_demo(): iota: e[5] " << endl;std::iota(e, e + 5, 'e');for (size_t i = 0; i < 5; i++){cout <<" iota = " << e[i] << endl;}//结果:值顺序递增iota_demo(): old : d[5] = { 0 }iota_demo(): iota: d[5] = { 10 11 12 13 14 }iota_demo(): old : e[5] = { 'a' }iota_demo(): iota: e[5] iota = e iota = f iota = g iota = h iota = i值顺序递增 end.
多值赋值及函数返回多值
这个功能在Go语言中相当方便,C++中则需要使用tuple和 tie等才能实现,有点麻烦,但效果是一样的。
Golang
func tuple_demo()(int,string){a,b := 1,2fmt.Println("a:",a," b:",b);c,d := b,afmt.Println("c:",c," d:",d);return 168, "函数返回的字符串"}C++
tuple<int, string> tuple_demo(){tuple<int, string> ret;ret = make_tuple(168, "函数返回的字符串");cout << "tuple_demo(): " << get<0>(ret) << " " << (get<1>(ret)).c_str() << endl;auto triple = make_tuple(5, 6, 7);cout << "tuple_demo(): " << get<0>(triple) << " " << get<1>(triple) << " " << get<2>(triple) << endl;int ti;string ts;tie(ti, ts) = make_tuple(10, "xcl--将数字和字符赋值给两个变量");cout << "tuple_demo(): " << ti << " " << ts.c_str() << endl;return ret;}//调用:int ti;string ts;tie(ti, ts) = tuple_demo();cout << "main() <- tuple_demo(): " << ti << " " << ts.c_str() << endl;//结果:多值赋值及函数返回多值tuple_demo(): 168 函数返回的字符串tuple_demo(): 5 6 7tuple_demo(): 10 xcl--将数字和字符赋值给两个变量main() <- tuple_demo(): 168 函数返回的字符串多值赋值及函数返回多值 end.
map查找
Go语言中map的查找特别方便. 要找个值,直接map[key]就出来了。C++也可以直接用find(key)的方式,但Go语言直接有个
found的变量,能告知是否有找到,这个要比C++去比end(),要直观些,也可以少打些字。
Golang
var mMap = map[string]int {"a":1,"b":2,"c":3}val,found := mMap["b"]if found {fmt.Println("found :",val);}else{fmt.Println("not found");}
C++
typedef map <string, int > map_str_int;tuple<string, int, bool> mapfind_demo(map_str_int myMap, string key){map_str_int::iterator pos;pos = myMap.find(key);if (pos == myMap.end()){return make_tuple("", 0, false);}else{return make_tuple(pos->first, pos->second, true);}}//调用:auto myMap = map_str_int{ { "aa", 1 }, { "bb", 2 }, { "cc", 3 } };string mpKey;int mpValue;bool mpFound = false;tie(mpKey, mpValue, mpFound) = mapfind_demo(myMap, "bb");if (mpFound){cout << "mapfind_demo: found" << endl;}else{cout << "mapfind_demo: not found" << endl;}
可变参数
可变参数是指函数的最后一个参数可以接受任意个参数,我在用Go语言实现的args_demo()例子中,用了效果一样的两种不同
调用方法来展示Go语言对这个下的功夫。然后可以再看看通过C++模板实现的,一个比较有代表性的Print函数来感受感受C++
对这个可变参数的处理方式。
Golang
func args_demo(first int,args ...int){fmt.Println("ars_demo first:",first)for _,i := range args {fmt.Println("args:",i)}}//调用args_demo(5,6,7,8);mArr := []int{ 5, 6, 7,8}args_demo(mArr[0],mArr[1:]...);fmt.Println("fmtPrintln(): ", 1, 2.0, "C++11", "Golang");执行结果变量fmtPrintln(): 1 2 C++11 Golangars_demo first: 5args: 6args: 7args: 8ars_demo first: 5args: 6args: 7args: 8
C++
template<typename T> void fmtPrintln(T value){cout << value << endl;}template<typename T, typename... Args>void fmtPrintln(T head, Args... args){cout << head << " ";fmtPrintln(args...);}//调用fmtPrintln("fmtPrintln(): ", 1, 2.0, "C++11", "Golang");//执行结果:变长参数fmtPrintln(): 1 2 C++11 Golang变长参数 end.
回调函数
对比看看两种语言函数的回调处理,实现方法没啥差异。
Golang
type funcType func(string)func printFunc(str string){fmt.Println( "callFunc() -> printFunc():",str)}func callFunc(arg string,f funcType){f(arg)}callFunc("回调就是你调我,我调它,大家一起玩。",printFunc)
C++
void printFunc(string arg){cout << "callFunc() -> printFunc():" << arg.c_str() << endl;}typedef void(*callf)(string);void callFunc(callf pFunc, string arg){ //void(*pFunc)(string)pFunc(arg);}callFunc(printFunc, "回调就是你调我,我调它,大家一起玩。");
泛型
C++泛型就不用多说了,都知道有多强大。Go语言要加入这个不知道是啥时候的事,不过通过简单的反射,还
是可以实现类似的功能,但代码有点长。
Golang
func compare(v1, v2 interface{}) (int, error) {switch v1.(type) {case int:if v1.(int) < v2.(int) {return -1, nil} else if v1.(int) == v2.(int) {return 0, nil}case int8:if v1.(int8) < v2.(int8) {return -1, nil} else if v1.(int8) == v2.(int8) {return 0, nil}case int32:if v1.(int32) < v2.(int32) {return -1, nil} else if v1.(int32) == v2.(int32) {return 0, nil}//省略......default:return -2, errors.New("未能处理的数据类型.")}return 1, nil}//调用:v1 := 13v2 := 53ret, err := compare(v1, v2)if err != nil {fmt.Println(err)return}switch ret {case -1:fmt.Println("v1 < v2")case 0:fmt.Println("v1 == v2")case 1:fmt.Println("v1 > v2")default:fmt.Println("defualt")}
C++
template <typename T> int compare(const T v1, const T v2){if (v1 < v2){cout << "compare(): v1 < v2" << endl;return -1;}else if (v1 == v2){cout << "compare(): v1 == v2" << endl;return 0;}else{cout << "compare(): v1 > v2" << endl;return 1;}}//调用:int i1 = 5, i2 = 7;double d1 = 52.5, d2 = 10.7;compare(i1, i2);compare(d1, d2);
数组和切片(sclie)
数组/切片Go语言做得非常灵活,不一一举例,这里主要可以看看C++的。我用copy_n,copy_if 模拟二下简单的切片功能。
Golang
a := [5]int{ 1, 2, 3, 4, 5 } b := a[:3] c := a[1:2] fmt.Println(a) fmt.Println(b) fmt.Println(c) //运行结果:<span style="white-space:pre"></span>[1 2 3 4 5][1 2 3][2]
C++
int a[5] = { 1, 2, 3, 4, 5 };int b[3] = { 0 };int c[2] = { 0 };cout << "a[5] = { 1, 2, 3, 4, 5 }" << endl;cout << "array[:end_pos]: b = array[:3]" << endl;// array[:end_pos]copy_n(a, 3, b);for each (int var in b){cout << " " << var;}cout << endl;cout << "a[5] = { 1, 2, 3, 4, 5 }" << endl;cout << "array[begin_pos:end_pos]: c = array[1,2] " << endl;// array[begin_pos:end_pos]int begin_pos = 1;int subLen = sizeof(c) / sizeof(c[0]);int end_pos = begin_pos + subLen;copy_if(a + begin_pos, a + end_pos, c, [](int v){return true; });for each (int var in c){cout << " " << var ;}cout << endl;//运行结果:数组和切片(sclie)a[5] = { 1, 2, 3, 4, 5 }array[:end_pos]: b = array[:3] 1 2 3a[5] = { 1, 2, 3, 4, 5 }array[begin_pos:end_pos]: c = array[1,2] 2 3数组和切片(sclie) end.
很粗浅的分别实现下这几个点,体会是C++很强大,Golang更纯粹,少即是多。
Go语言和C++完整测试源码我放在此: 点击下载
可以自行下载编译。
MAIL: xcl_168@aliyun.com
Blog:http:/blog.csdn.net/xcl168
- Golang部份特性的C++对比实现
- Golang部份特性的C++对比实现
- javascript部份函数的实现
- Scala与Golang的并发实现对比----好问
- 对CLR以及GC--部份特性理解的总结
- Golang与C对比学习 (1)
- golang的特性和优势
- 2017年的golang、python、php、c++、c、java、Nodejs性能对比
- Golang服务器的网络层实现--总结对比常用epoll模型
- Golang语言和node.js的对比
- 继承std::string实现CString的部份方法
- C协程实现的效率对比
- GOLANG 实现的 fastcgi
- Golang实现的红黑树
- [Golang]golang中自动锁的实现
- [Golang]Map的一个绝妙特性
- [Golang]Map的一个绝妙特性
- 2. 使用golang特性编写的程序结构
- Android的json解析方式(一)
- hdu 1827 Summer Holiday(tarjan)
- 使用Bitmap createBitmap遇到的问题
- 26. Dubbo原理解析-监控
- ajax延迟加载数据
- Golang部份特性的C++对比实现
- android控件开发之progress
- java对象的强引用,软引用,弱引用和虚引用
- Android 仿QQ侧边栏,自定义view的学习 <Garry进阶(三)>
- 编写 ATL ActiveX 控件
- Android学习笔记(三)——理解android中的Menu
- RabbitMQ概念及环境搭建(二)RabbitMQ Broker管理
- MySQL5.6.12促成CPU的使用率 2000%的原因
- Eclipse中ndk配置