从C++到Go(三)

本文对比了C++和Go语言在运算符、常量、类型以及切片方面的差异。Go中的运算符优先级不同于C++,常量可以是无类型的,并在需要时自动获取类型。类型系统更加强制,不存在隐式类型转换。Go的切片是引用结构,允许高效地操作数组的一部分,而不需要复制。这种设计提供了灵活性,同时保持了安全性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

从C++到Go(三)

运算符

++--运算符不能在表达式中使用,只能在语句中使用。你不能编写如c = *p++的代码。*p++被解析为(*p)++。

Go的运算符优先级和C++不同。例如,在Go中,4 & 3 << 10, 而在C++中为4

Go运算符优先级:
1. *   /   %  <<  >>  &  &^
2. +   -   |  ^
3. ==  !=  <  <=  >   >=
4. &&
5. ||
C++运算符优先级 (only relevant operators):
1.  *    /   %
2.  +    -
3.  <<   >>
4.  <    <=  >   >=
5.  ==   !=
6.  &
7.  ^
8.  |
9.  &&
10. ||

常量

在Go中,常量可以是*无类型(untyped)*的。如果在声明中未给定类型,并且初始化表达式仅使用无类型的常量,那么这甚至适用于以const声明的常量。从无类型常量得来的值,当他用于需要一个类型值的上下文中时,会变成有类型的值。这个规则使常量使用起来更自由,无需常规的隐式类型转换。

var a uint
f(a + 1) // 无类型数值常量"1"变成有类型的uint

对于无类型数值常量或常量表达式的大小,语言本身不强加任何限制。仅当在需要类型常量中使用常量时才被限制。

const huge = 1 << 100
f(huge >> 98)

Go不支持枚举。作为替换,你可以使用iota在单独的const声明中来获得一系列的递增值。当为const省略初始化表达式时,它将重用前面的表达式。

const (
	red   = iota // red == 0
	blue         // blue == 1
	green        // green == 2
)

类型

C++和Go很类似,但不完全相同。C++的内置类型:有符号和无符号整数,32位和64位浮点数,结构体,指针等。在Go中,uint8int64,和类型名称的整数类型是语言的一部分,而不是建立在其大小取决于具体实现的整数之上(例如long long)。Go还提供了本地的stringmapchannel类型以及一流的数组和切片。字符串使用Unicode编码而不是ASCII。

Go比C++更加强类型,特别地,在Go中不存在隐式类型转换,只有显示类型转换。这提供了额外的安全性和自由,但要付出一些额外的打字费用。在Go中也没有union,因为这将会颠覆类型系统。然而,Go中的interface{}(将在下面讲解)提供了一个类型安全的代替品。

C++和Go都支持类型别名(在C++中为typedef,在Go中为type)。然而,与C++不同的是,Go对待别名为不同的类型。因此,以下代码在C++中有效:

// C++
typedef double position;
typedef double velocity;

position pos = 218.0;
velocity vel = -9.8;

pos += vel;

但是这在Go中无效:

type position float64
type velocity float64

var pos position = 218.0
var vel velocity = -9.8

pos += vel // 无效: 类型不匹配
// pos += position(vel)  // 有效

即使对于非别名类型也是如此:一个int和一个uint不能在一个没有显式类型转换的表达式中使用。

与C++不同,Go不允许指针转换成整数或从整数转换而来。然而,Go的unsafe包能够让你在必要时显式地绕过这个在安全机制(例如,用于低级系统的代码)。

切片

从概念上来说,一个切片是一个由三个字段组成的结构体:指向数组的指针,长度和容量。切片支持通过[]运算符去访问底层数组的元素。内置函数len返回切片的长度。内置函数cap返回切片的容量。

给定一个数组或另一个切片,可以通过a[i:j]来创建一个新的切片。这将创建一个引用a的新的切片,起始位置为i,结束位置为j之前。它的长度为j - i。如果i被忽略,切片将从0开始。如果j被忽略,切片将结束于len(a)。新的切片和a引用相同的数组。该语句的两个含义是:①使用a可以看到使用新切片进行的更改,并且②创建切片的开销是很低的;不需要拷贝底层数组。新切片的容量是a的容量减i。一个数组的容量是这个数组的长度。

这意味着Go在某些情况下使用切片,而C ++使用指针。如果你创建一个类型为[100]byte的值(一个100个byte的数组)并且你想将他传递给一个函数但不想拷贝该数组,你应该将函数参数的类型声明为[]byte,然后传递数组的切片(a[:],将传递整个数组)。与C++不同,不需要传递数组的长度;它可以通过len函数获得。

切片语法也可以用于一个字符串。它返回一个新字符串,它的值为原始字符串的一个字串。因为字符串是不可变的,所以字符串切片可以实现为无需为切片的内容分配新的存储空间。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值