GO的第四天,基础数据类型

Mr_J · · 555 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

Go语言将数据类型分为四类:基础类型、复合类型、引用类型和接口类型。基础类型,包括:数字、字符串和布尔型。今天我们大体上讲下这几种:整型,浮点数,布尔型,字符串型,常量。《GO语言圣经》里还介绍了一种,那就是复数,为什么我不讲复数呢?主要有两个原因,第一个原因:感觉基本上不常用。第二个原因:本人的数学知识都已经还给老师了。

好了,不多废话,我们开始吧!

整型

Go语言同时提供了有符号和无符号类型的整数运算。这里有int8、int16、int32和int64四种截然不同大小的有符号整数类型,分别对应8、16、32、64bit大小的有符号整数,与此对应的是uint8、uint16、uint32和uint64四种无符号整数类型。这几个有什么区别呢,我们看代码,你就基本可以知道了。

var u uint8 = 255
fmt.Println(u, u+1, u*u) // "255 0 1"

var i int8 = 127
fmt.Println(i, i+1, i*i) // "127 -128 1"

其中有符号整数采用2的补码形式表示,也就是最高bit位用来表示符号位,一个n-bit的有符号数的值域是从$-2^{n-1}$到$2^{n-1}-1$。无符号整数的所有bit位都用于表示非负数,值域是0到$2^n-1$。例如,int8类型整数的 值域 是从-128到127,而uint8类型整数的 值域 是从0到255。

浮点数

浮点数的范围极限值可以在math包找到。常量math.MaxFloat32表示float32能表示的最大数值,大约是 3.4e38;对应的math.MaxFloat64常量大约是1.8e308。它们分别能表示的最小值近似为1.4e-45和4.9e-324。
浮点数的字面值可以直接写小数部分,像这样:

const e = 2.71828 // (approximately)

小或很大的数最好用科学计数法书写,通过e或E来指定指数部分:

const Avogadro = 6.02214129e23  // 阿伏伽德罗常数
const Planck   = 6.62606957e-34 // 普朗克常数

布尔型

一个布尔类型的值只有两种:true和false。
布尔值并不会隐式转换为数字值0或1,反之亦然。必须使用一个显式的if语句辅助转换。如果需要经常做类似的转换, 包装成一个函数会更方便:

func btoi(b bool) int {
    if b {
        return 1
    }
    return 0
}

数字到布尔型的逆转换则非常简单, 不过为了保持对称, 我们也可以包装一个函数:

func itob(i int) bool { return i != 0 }

字符串

一个字符串是一个 不可改变 的字节序列。GO的字符串操作跟python的字符串操作差不多。

s := "hello, world"
fmt.Println(len(s))     // "12"
fmt.Println(s[0], s[7]) // "104 119" ('h' and 'w')
fmt.Println(s[0:5]) // "hello"

子字符串操作s[i:j]基于原始的s字符串的第i个字节开始到第j个字节(并不包含j本身)生成一个新字符串。生成的新字符串将包含j-i个字节。
不管i还是j都可能被忽略,当它们被忽略时将采用0作为开始位置,采用len(s)作为结束的位置。

fmt.Println(s[:5]) // "hello"
fmt.Println(s[7:]) // "world"
fmt.Println(s[:])  // "hello, world"

字符串面值

这个通俗的讲就是php当中的heredoc,PHP当中是这样用的:


<?php
    echo <<<EOF
    Thisis a Headline
    Thisis the first line.
    Thisis the second line.
EOF;

一个原生的字符串面值形式是`...`,使用反引号代替双引号。go的语法:

const GoUsage = `Go is a tool for managing Go source code.

Usage:
    go command [arguments]
...`

字符串与Byte切片

一个字符串是包含的 只读字节数组,一旦创建,是 不可变的。相比之下,一个字节slice的元素则可以 自由地修改
字符串和字节slice之间可以相互转换:

s := "abc"
b := []byte(s)
s2 := string(b)

标准库中有四个包对字符串处理尤为重要:bytesstringsstrconvunicode包。strings包提供了许多如字符串的查询、替换、比较、截断、拆分和合并等功能。

bytes包也提供了很多类似功能的函数,但是针对和字符串有着相同结构的[]byte类型。因为字符串是只读的,因此逐步构建字符串会导致很多分配和复制。在这种情况下,使用bytes.Buffer类型将会更有效。

strconv包提供了布尔型、整型数、浮点数和对应字符串的相互转换,还提供了双引号转义相关的转换。

unicode包提供了IsDigit、IsLetter、IsUpper和IsLower等类似功能,它们用于给字符分类。每个函数有一个单一的rune类型的参数,然后返回一个布尔值。而像ToUpper和ToLower之类的转换函数将用于rune字符的大小写转换。所有的这些函数都是遵循Unicode标准定义的字母、数字等分类规范。strings包也有类似的函数,它们是ToUpper和ToLower,将原始字符串的每个字符都做相应的转换,然后返回新的字符串。

bytes包还提供了Buffer类型用于字节slice的缓存。一个Buffer开始是空的,但是随着string、byte或[]byte等类型数据的写入可以动态增长,一个bytes.Buffer变量并不需要初始化,因为零值也是有效的:

// intsToString is like fmt.Sprint(values) but adds commas.
func intsToString(values []int) string {
    var buf bytes.Buffer
    buf.WriteByte('[')
    for i, v := range values {
        if i > 0 {
            buf.WriteString(", ")
        }
        fmt.Fprintf(&buf, "%d", v)
    }
    buf.WriteByte(']')
    return buf.String()
}

func main() {
    fmt.Println(intsToString([]int{1, 2, 3})) // "[1, 2, 3]"
}

常量

常量表达式的值在 编译期 计算,而不是在 运行期。每种常量的潜在类型都是基础类型:boolean、string或数字。

const pi = 3.14159

和变量声明一样,可以批量声明多个常量;这比较适合声明一组相关的常量:

const (
    e  = 2.71828182845904523536028747135266249775724709369995957496696763
    pi = 3.14159265358979323846264338327950288419716939937510582097494459
)

常量间的所有 算术运算逻辑运算比较运算 的结果也是常量,对常量的类型转换操作或以下函数调用都是返回常量结果:len、cap、real、imag、complex和unsafe.Sizeof。

一个常量的声明也可以包含一个类型和一个值,但是如果没有显式指明类型,那么将从右边的表达式推断类型。

const noDelay time.Duration = 0
fmt.Printf("%T %[1]v\n", noDelay)   // time.Duration 0 

iota常量生成器

常量声明可以使用 iota常量生成器 初始化,它用于生成一组以 相似规则 初始化的常量,但是不用每行都写一遍初始化表达式。在一个const声明语句中,在第一个声明的常量所在的行,iota将会被置为0,然后在每一个有常量声明的行加一。

下面是来自time包的例子,它首先定义了一个Weekday命名类型,然后为一周的每天定义了一个常量,从周日0开始。在其它编程语言中,这种类型一般被称为枚举类型。

type Weekday int

const (
    Sunday Weekday = iota
    Monday
    Tuesday
    Wednesday
    Thursday
    Friday
    Saturday
)

周日将对应0,周一为1,如此等等。

参考

《GO语言圣经》


有疑问加站长微信联系(非本文作者)

本文来自:Segmentfault

感谢作者:Mr_J

查看原文:GO的第四天,基础数据类型

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

555 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传