文章首发公众号「码农吴先生」, 欢迎订阅关注。html
本篇是「对比Python学习Go」 系列的第三篇,本篇文章咱们来看下Go的基本数据结构。Go的环境搭建,可参考以前的文章「对比Python学习Go」- 环境篇。废话很少说,下面开始咱们的对比学习。python
Go的基本数据类型主要以下:golang
bool
string
int int8 int16 int32 int64
uint uint8 uint16 uint32 uint64 uintptr
byte // uint8 的别名
rune // int32 的别名
// 表明一个Unicode码
float32 float64
complex64 complex128
复制代码
Go 语言自己更偏向底层,对内存占用和性能的要求更高,除了有普通的数据类型以外,还有定长的数据类型,方便在不一样场景使用,提升性能。安全
int,uint 和 uintptr 类型在32位的系统上通常是32位,而在64位系统上是64位。官方推荐在使用整数时,首选 int
类型,仅当有特别的理由(你知道为何要这么作)才使用定长整数类型或者无符号整数类型。markdown
Python 的基本数据类型以下:数据结构
int
long # 仅在python 2 版本中有
float
complex # 复数型
str # 字符串 python2中有bytes(str)和unicode,python3中只有str类型 默认支持unicode编码
bool # 布尔型
None # 空值类型
复制代码
在Python中,各种型占用的字节大小有Python解释器动态分配。不一样的Python版本,分配机制也略有区别。用户可以使用sys.getsizeof()
来具体查看各种型占用的字节数。Python3 中大体以下:函数
Bytes type scaling notes
28 int +4 bytes about every 30 powers of 2
37 bytes +1 byte per additional byte
49 str +1-4 per additional character (depending on max width)
48 tuple +8 per additional item
64 list +8 for each additional
224 set 5th increases to 736; 21nd, 2272; 85th, 8416; 341, 32992
240 dict 6th increases to 368; 22nd, 1184; 43rd, 2280; 86th, 4704; 171st, 9320
136 func def does not include default args and other attrs
1056 class def no slots
56 class inst has a __dict__ attr, same scaling as dict above
888 class def with slots
16 __slots__ seems to store in mutable tuple-like structure
first slot grows to 48, and so on.
复制代码
有兴趣深刻研究的,可参考这个stackoverflow的讨论。oop
其实,在大多数状况下,咱们使用Python来编写代码,不用太考虑类型的占用大小问题,解释器已经帮咱们作好了内存的分配。对于内存而言,咱们更应该关注的是大内存占用的对象的及时释放问题。post
package main
import "fmt"
// 常量定义和赋值 ,常量能够是字符、字符串、布尔或数字类型,有关键字 const 定义
const Pi = 3.14
// 变量定义和赋值 使用关键字 var 定义
var a = "initial"
var (
x int
y int
)
func main() {
fmt.Println(a)
// 相同类型定义可省略前边变量的数据类型
var b, c int = 1, 2
fmt.Println(b, c)
// 定义布尔型并赋值
var d = true
fmt.Println(d)
// 只定义没有赋值
var e int
fmt.Println(e)
// := 为变量赋值简写形式,只有在函数中才能使用。常量在哪都不能使用。
f := "short"
fmt.Println(f)
}
复制代码
代码中 e
只定义并无赋值,此时它会有一个默认的初始值,在Go中把这个初始值叫作「零值」。性能
在使用数值类型0值的时候必定要注意精度问题,在不一样语言中精度要求可能不一样,这极可能形成你序列化和反序列化的失败。
Python 是动态,弱类型语言。在赋值前不须要声明,左侧对象的类型由值的类型肯定。
>>> a = 123
>>> b = '123'
>>> c = True
>>> print(type(a),type(b),type(c))
(<type 'int'>, <type 'str'>, <type 'bool'>)
a,b = 1,2 # 批量复制
c = d = 3 # 连续复制
a,b = b,a # ab 值交换
复制代码
// 数值型可直接使用 表达式 T(v)将值 v 转换为类型 T
var i int = 42
// int --> float64
var f float64 = float64(i)
// int --> uint
var u uint = uint(f)
// 数值和字符串的转换 须要使用 strconv 库,它为咱们提供了不少转换方法
s := "123456"
// string --> int
i, _ := strconv.Atoi(s)
fmt.Println("i type:", reflect.TypeOf(i))
// string --> int64
i64, _ := strconv.ParseInt(s, 10, 64)
fmt.Println("i64 type:", reflect.TypeOf(i64))
// string --> float64
f64, _ := strconv.ParseFloat(s, 64)
fmt.Println("f64 type:", reflect.TypeOf(f64))
// int --> string
s1 := strconv.Itoa(i) //数字变成字符串
fmt.Println("s1 type:", reflect.TypeOf(s1))
// int64 --> string
s2:=strconv.FormatInt(i64,10)
fmt.Println("s1 type:", reflect.TypeOf(s2))
复制代码
Python中可直接将各种型对象使用类型方法转换。
n = 20
# int --> float
f = float(n)
# int --> str
s = str(n)
# str --> int
n1 = int(s)
# str --> float
f1 = float(s)
复制代码
name := "DeanWu"
// 相加
fmt.Println("我叫" + name)
// 下标取值
fmt.Println(name[0]) // 直接取,是对应的ascii码,须要传下
fmt.Printf("%c\n", name[0])
fmt.Println(name[:3])
// 使用内建函数len获取字符串长度
fmt.Println(len(name))
// 字符串包含
fmt.Println(strings.Contains(name, "a"))
// 字符串开头,结尾
fmt.Println(strings.HasPrefix(name, "D"))
fmt.Println(strings.HasSuffix(name, "u"))
// 字符串分割组合
arr := strings.Split(name, "e")
fmt.Println(strings.Join(arr, "e"))
// 字符串格式化
fmt.Printf("%s, %.2f \n", a, f64)
fmt.Println(fmt.Sprintf("我叫,%s", name))
/* %v 相应值的默认格式。在打印结构体时,“加号”标记(%+v)会添加字段名 %#v 相应值的 Go 语法表示 %T 相应值的类型的 Go 语法表示 %% 字面上的百分号,并不是值的占位符 %t 单词 true 或 false。 %b 二进制表示 %c 相应 Unicode 码点所表示的字符 %d 十进制表示 %o 八进制表示 %q 单引号围绕的字符字面值,由 Go 语法安全地转义 %x 十六进制表示,字母形式为小写 a-f %X 十六进制表示,字母形式为大写 A-F %U Unicode 格式:U+1234,等同于 “U+%04X” %b 无小数部分的,指数为二的幂的科学计数法,与 strconv.FormatFloat 的 ‘b’ 转换格式一致。例如 -123456p-78 %e 科学计数法,例如 -1234.456e+78 %E 科学计数法,例如 -1234.456E+78 %f 有小数点而无指数,例如 123.456 %g 根据状况选择 %e 或 %f 以产生更紧凑的(无末尾的 0)输出 %G 根据状况选择 %E 或 %f 以产生更紧凑的(无末尾的 0)输出 %s 字符串或切片的无解译字节 %q 双引号围绕的字符串,由 Go 语法安全地转义 %x 十六进制,小写字母,每字节两个字符 %X 十六进制,大写字母,每字节两个字符 %p 十六进制表示,前缀 0x */
复制代码
name = "DeanWu"
# 相加
print("我叫" + name)
# 下标取值
print(name[0])
print(name[:3])
# 使用内建函数len获取字符串长度
print(len(name))
# 字符串包含
print("a" in name)
# 字符串开头,结尾
print(name.startswith("D"))
print(name.endswith("u"))
# 字符串分割组合
name_list = name.split("e")
print("e".join(name_list))
# 字符串格式化
print("%s " % name )
%d 整数
%f 浮点数
%s 字符串
%x 十六进制整数
# format 格式化
print("你好,{}".format(name))
print("你好,{0}, {1}".format(name, "我是第二个"))
# fstring 格式化
print(f'我是,{name}')
复制代码
编码
Go 原生支持Unicode,经常使用编码为UTF-8。
Python2中的默认编码为ASCII编码,Python3中使用的则是UTF-8编码。
篇幅有限,更多编码问题可参考我以前总结的Python教程:字符串与编码章节
操做符
go操做符:
+ & += &= && == != ( )
- | -= |= || < <= [ ]
* ^ *= ^= <- > >= { }
/ << /= <<= ++ = := , ;
% >> %= >>= -- ! ... . :
&^ &^=
复制代码
python操做符:
+ == = & and
- != += | or
* <> -= ^ not
/ > *= ~
% < /= <<
** >= >>
// <=
复制代码
关键字
go关键字:
break default func interface select
case defer go map struct
chan else goto package switch
const fallthrough if range type
continue for import return var
复制代码
python 关键字:
>>> import keyword
>>> keyword.kwlist
['and', 'as', 'assert', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'exec', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'not', 'or', 'pass', 'print', 'raise', 'return', 'try', 'while', 'with', 'yield']
复制代码
注释
go 注释:
// 单行注释
/* 多行 注释 */
复制代码
python 注释:
# 单行注释
''' 多行 注释 '''
""" 多行 注释 """
复制代码
本篇文章咱们对比学习了Go的基本数据结构,从基本数据结构的设计,咱们能够看出Go的基本类型,更精细,对用户暴露出更多的可控性。在使用上,都比较简单,清晰明了。
好了,本篇到这里了,敬请期待下篇更新。
我是DeanWu,一个努力成为真正SRE的人。
关注公众号「码农吴先生」, 可第一时间获取最新文章。回复关键字「go」「python」获取我收集的学习资料,也可回复关键字「小二」,加我wx,聊技术聊人生~