加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

Golang部份特性的C++对比实现

发布时间:2020-12-16 18:21:03 所属栏目:大数据 来源:网络整理
导读:今天看到一篇文章C++ 逐渐 Python 化, 我个人是认为这个说法是不成立的,但这里面的一些特性对比引起了我的兴趣。 我想尝试下,Go语言所带的一些东西,在C++11中是如何做的,应当很有意思。所以刷刷刷,就有了下面的东西。 目录: 字符串字面值 变量初始化 l

今天看到一篇文章<<C++ 逐渐 Python 化>>, 我个人是认为这个说法是不成立的,但这里面的一些特性对比引起了我的兴趣。

我想尝试下,Go语言所带的一些东西,在C++11中是如何做的,应当很有意思。所以刷刷刷,就有了下面的东西。

目录:

字符串字面值
变量初始化
lambda
值顺序递增
多值赋值及函数返回多值
map查找
可变参数
回调函数
泛型
数组和切片


字面值

这个东西在两种语言中都有比较好的解决方式.Go语言用" ` "符号,C++使用R(" )"这种方式。可以省掉不少转义符的输入。

Golang

[cpp] view plain copy
  1. path:=`c:abcGG再也不用烦转义符了`
  2. mulln:=`"(C++/Golang
  3. aa'aaaCplusplus/gogogo
  4. author"xiongchuanliang
  5. `
  6. fmt.Println(path)
  7. fmt.Println(mulln)
C++

copy
stringpath=R"(c:abcGG再也不用烦转义符了)";
  • cout<<"单行:"<<path.c_str()<<endl;
  • stringmuln=R"(C++/Golang
  • )";
  • cout<<"多行:"<<muln.c_str()<<endl;
  • 变量初始化

    现在开发语言的初始化都差不多,都能很方便的定义时初始化,循环也是如下面中的C++ for循环和Go语言中的"for : rang"

    形式基本一样。 另外C++的auto,Go语言中的":=",都能省代码的好东西。不过要多提一句,Go语言支持多重赋值,并且变量都

    是默认就已初始化好。同时,Go语言也支持指针,但它的指针要安全得多。

    Golang

    copy
    varkint
  • fmt.Println(k)
  • mArr:=[]int{1,2,3}
  • varmMap=map[string]int{"a":1,"b":2}
  • fmt.Printf("array:%vnmap:%vn",mArr,mMap)
  • i:=10
  • pi:=&i//*i
  • ppi:=&pi//**int
  • fmt.Println(i,*pi,**ppi)
  • //结果:
  • 0
  • array:[123]
  • map:map[a:1b:2]
  • 101010
  • C++

    copy
    intmArr[]={1,3};
  • automList=vector<int>{1,3,4};
  • automMap=map<int,string>{{1,"aa"},{2,"bb"}};
  • cout<<"vector:";
  • for(constint&x:mList)
  • cout<<x<<"";
  • cout<<endl;
  • cout<<"map:";
  • constauto&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

    copy
    mArr:=[] fun:=func(i,vint){
  • fmt.Printf("idx:%dvalue:%dn",i,v)
  • }
  • foridx,val:=rangemArr{
  • fun(idx,val)
  • }
  • C++

    copy
    intarr[]={1,248); line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important; list-style-position:outside!important"> for_each(begin(arr),end(arr),[](intn){cout<<n<<endl;});
  • autofunc=[](intn){cout<<n<<endl;};
  • for_each(begin(arr),func);
  • 值顺序递增(iota)

    iota这个小东西很有特点,两种语言都支持且都是让数据顺序递增,从功能上看C++的iota似乎更强大灵活些。 但有意思的是,

    似乎在Go语言中,iota的使用频率要高得多,被大量的用于像const定义之类的地方,有意思。

    Golang

    copy
    const(
  • Red=iota
  • Green
  • Blue
  • )
  • fmt.Println("Red:",Red,"Gree:",Green,"Blue:",Blue);
  • C++

    copy
    intd[5]={0};
  • std::iota(d,d+5,10);
  • cout<<"iota_demo():old:d[5]={0}"<<endl;
  • cout<<"iota_demo():iota:d[5]={";
  • foreach(intvarind)
  • {
  • cout<<var<<"";
  • }
  • cout<<"}"<<endl;
  • chare[5]={'a'};
  • charf[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_ti=0;i<5;i++)
  • {
  • cout<<"iota="<<e[i]<<endl;
  • 值顺序递增
  • iota_demo():old:d[5]={0}
  • iota_demo():iota:d[5]={1011121314}
  • 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

    copy
    functuple_demo()( a,b:=1,2
  • fmt.Println("a:",a,"b:",b);
  • c,d:=b,a
  • fmt.Println("c:",c,"d:",d);
  • return168,"函数返回的字符串"
  • }
  • C++
    copy
    tuple< tuple< ret=make_tuple(168,"函数返回的字符串");
  • cout<<"tuple_demo():"<<get<0>(ret)<<""<<(get<1>(ret)).c_str()<<endl;
  • autotriple=make_tuple(5,6,7);
  • cout<<"tuple_demo():"<<get<0>(triple)<<""<<get<1>(triple)<<""<<get<2>(triple)<<endl;
  • intti;
  • stringts;
  • tie(ti,ts)=make_tuple(10,"xcl--将数字和字符赋值给两个变量");
  • cout<<"tuple_demo():"<<ti<<""<<ts.c_str()<<endl;
  • returnret;
  • //调用:
  • intti;
  • stringts;
  • tie(ti,ts)=tuple_demo();
  • cout<<"main()<-tuple_demo():"<<ti<<""<<ts.c_str()<<endl;
  • //结果:
  • 多值赋值及函数返回多值
  • tuple_demo():168函数返回的字符串
  • tuple_demo():567
  • tuple_demo():10xcl--将数字和字符赋值给两个变量
  • main()<-tuple_demo():168函数返回的字符串
  • 多值赋值及函数返回多值end.
  • map查找

    Go语言中map的查找特别方便. 要找个值,直接map[key]就出来了。C++也可以直接用find(key)的方式,但Go语言直接有个

    found的变量,能告知是否有找到,这个要比C++去比end(),要直观些,也可以少打些字。

    Golang

    copy
    varmMap=map[string]"b":2,"c":3}
  • val,found:=mMap["b"]
  • iffound{
  • fmt.Println("found:",val);
  • }else{
  • fmt.Println("notfound");
  • copy
    typedefmap<string,int>map_str_int;
  • tuple<string,bool>mapfind_demo(map_str_intmyMap,stringkey){
  • map_str_int::iteratorpos;
  • pos=myMap.find(key);
  • if(pos==myMap.end()){
  • returnmake_tuple("",false);
  • returnmake_tuple(pos->first,pos->second,153); background-color:inherit; font-weight:bold">true);
  • //调用:
  • automyMap=map_str_int{{"aa",1},{"bb",2},{"cc",3}};
  • stringmpKey;
  • intmpValue;
  • boolmpFound=false;
  • tie(mpKey,mpValue,mpFound)=mapfind_demo(myMap,"bb");
  • if(mpFound){
  • cout<<"mapfind_demo:found"<<endl;
  • cout<<"mapfind_demo:notfound"<<endl;
  • }
  • 可变参数

    可变参数是指函数的最后一个参数可以接受任意个参数,我在用Go语言实现的args_demo()例子中,用了效果一样的两种不同

    调用方法来展示Go语言对这个下的功夫。然后可以再看看通过C++模板实现的,一个比较有代表性的Print函数来感受感受C++

    对这个可变参数的处理方式。

    Golang

    copy
    funcargs_demo(firstint){
  • fmt.Println("ars_demofirst:",first)
  • for_,i:=rangeargs{
  • fmt.Println("args:",i)
  • //调用
  • args_demo(5,7,8);
  • int{5,8}
  • args_demo(mArr[0],mArr[1:]...);
  • fmt.Println("fmtPrintln():",1,2.0,"C++11","Golang");
  • 执行结果
  • 变量fmtPrintln():12C++11Golang
  • ars_demofirst:5
  • args:6
  • args:7
  • args:8
  • args:8
  • copy

    template<typenameT>voidfmtPrintln(Tvalue){
  • cout<<value<<endl;
  • typenameT,153); background-color:inherit; font-weight:bold">typename...Args>
  • voidfmtPrintln(Thead,Args...args)
  • cout<<head<<"";
  • fmtPrintln(args...);
  • fmtPrintln("fmtPrintln():",0); background-color:inherit">//执行结果:
  • 变长参数
  • fmtPrintln():12C++11Golang
  • 变长参数end.

  • 回调函数

    对比看看两种语言函数的回调处理,实现方法没啥差异。

    copy

    typefuncTypefunc(string)
  • funcprintFunc(strstring){
  • fmt.Println("callFunc()->printFunc():",str)
  • funccallFunc(argstring,ffuncType){
  • f(arg)
  • callFunc("回调就是你调我,我调它,大家一起玩。",printFunc)

  • C++

    copy
    voidprintFunc(stringarg){
  • cout<<"callFunc()->printFunc():"<<arg.c_str()<<endl;
  • typedefvoid(*callf)(string);
  • voidcallFunc(callfpFunc,stringarg){//void(*pFunc)(string)
  • pFunc(arg);
  • callFunc(printFunc,"回调就是你调我,我调它,大家一起玩。");

  • 泛型

    C++泛型就不用多说了,都知道有多强大。Go语言要加入这个不知道是啥时候的事,不过通过简单的反射,还

    是可以实现类似的功能,但代码有点长。

    Golang

    copy
    funccompare(v1,v2interface{})(switchv1.(type){
  • caseint:
  • ifv1.(int)<v2.(return-1,nil
  • elseint)==v2.(return0,153); background-color:inherit; font-weight:bold">caseint8:
  • ifv1.(int8)<v2.(int8){
  • ifv1.(int8)==v2.(int8){
  • caseint32:
  • ifv1.(int32)<v2.(int32){
  • ifv1.(int32)==v2.(int32){
  • //省略......
  • default:
  • return-2,errors.New("未能处理的数据类型.")
  • return1,248); line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important; list-style-position:outside!important"> v1:=13
  • v2:=53
  • ret,err:=compare(v1,v2)
  • iferr!=nil{
  • fmt.Println(err)
  • return
  • switchret{
  • case-1:
  • fmt.Println("v1<v2")
  • case0:
  • fmt.Println("v1==v2")
  • case1:
  • fmt.Println("v1>v2")
  • default:
  • fmt.Println("defualt")
  • }
  • C++

    copy
    typenameT>intcompare(constTv1,153); background-color:inherit; font-weight:bold">constTv2){
  • if(v1<v2){
  • cout<<"compare():v1<v2"<<endl;
  • return-1;
  • if(v1==v2){
  • cout<<"compare():v1==v2"<<endl;
  • return0;
  • else{
  • cout<<"compare():v1>v2"<<endl;
  • return1;
  • inti1=5,i2=7;
  • doubled1=52.5,d2=10.7;
  • compare(i1,i2);
  • compare(d1,d2);

  • 数组和切片(sclie)

    数组/切片Go语言做得非常灵活,不一一举例,这里主要可以看看C++的。我用copy_n,copy_if 模拟二下简单的切片功能。

    Golang

    copy
    a:=[5] b:=a[:3]
  • c:=a[1:2]
  • fmt.Println(a)
  • fmt.Println(b)
  • fmt.Println(c)
  • //运行结果:<spanstyle="white-space:pre"></span>
  • [12345]
  • [123]
  • [2]
  • copy

    inta[5]={1,5};
  • intb[3]={0};
  • intc[2]={0};
  • cout<<"a[5]={1,5}"<<endl;
  • cout<<"array[:end_pos]:b=array[:3]"<<endl;
  • //array[:end_pos]
  • copy_n(a,b);
  • intvarinb)
  • cout<<""<<var;
  • cout<<"a[5]={1,5}"<<endl;
  • cout<<"array[begin_pos:end_pos]:c=array[1,2]"<<endl;
  • //array[begin_pos:end_pos]
  • intbegin_pos=1;
  • intsubLen=sizeof(c)/sizeof(c[0]);
  • intend_pos=begin_pos+subLen;
  • copy_if(a+begin_pos,a+end_pos,87); background-color:inherit; font-weight:bold">intv){returntrue;});
  • intvarinc)
  • cout<<""<<var;
  • cout<<endl;
  • //运行结果:
  • 数组和切片(sclie)
  • a[5]={1,5}
  • array[:end_pos]:b=array[:3]
  • 123
  • a[5]={1,5}
  • array[begin_pos:end_pos]:c=array[1,2]
  • 23
  • 数组和切片(sclie)end.

  • 很粗浅的分别实现下这几个点,体会是C++很强大,Golang更纯粹,少即是多。

    Go语言和C++完整测试源码我放在此:点击下载

    可以自行下载编译。

    (编辑:李大同)

    【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

      推荐文章
        热点阅读