go 语言入门——基础数据类型(二)

一、布尔型(bool)
一个bool(布尔型 )的值只有两种:true和false。一般作为if或for(在Go语言中,为了精简循环语句,所以只有for而没有while等其他语句)的判断标准,也是比较符号(>、==等)的结果。

bool型可以和&&(AND)和||(OR)操作符相结合,并会有短路行为(当已经可以判断真假时,就会直接返回结果,而不会把后面的运算都计算)。

需要注意,&&的优先级大于||

bool型可以在if语句中和数字转换,0等价于false,1(也可以是>0的数)等价于true

二、字符串 string
一个字符串是一个不可改变的字节序列。字符串可以包含任意的数据,包括byte值0,但是通常是用来包含人类可读的文本。这里需要注意,Go语言中,字符串是不可以改变的,而一般的C系列,string类型可以近似的看成一个字符的数组,所以可以直接通过下标进行字符的修改,但是Go语言并不能这样操作。Go语言中string类型还有内置的len函数,返回字符串的字节数目(len(s)),可以用下标返回字节的值s[i].

s := "hello world" 
fmt.Println(len(s))     // "12"
fmt.Println(s[0], s[7]) // "104 119" ('h' and 'w'),这里需要注意,直接用fmt.Println打印某个字节,会得到对应的ASCII码的值
s[0] = 'L'              // compile error: cannot assign to s[0] ,Go语言不能改变string的值
c := s[len(s)]          // panic: index out of range,超过字符串范围会报错

Go语言和Python类似,也可以使用“:”用来进行切片操作,比如a[0:3]表示字符串a对第一个字符到第三个字符进行切片(如果a为"abcde",那么a[0:3]表示"abc")

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

Go语言中可以用"+"操作符将两个字符串连接构造成一个新的字符串。同样,也可以使用+=符号,但是需要注意的是,+=并不是改变了字符串的值,而是创建了一个新的字符串,并将这个新的字符串赋给了原来的变量。Go语言中的字符串也可以进行比较操作(所有的比较运算符),比较通过逐个字符比较完成

fmt.Println("goodbye" + s[5:]) // "goodbye, world"
s += " !!!!"                   //s为"hello world !!!!"
s <  "w"                       //true,因为h的ASCII码值小于w,此时已经比较出了结果,不需要后续的操作

1、字符串面值
字符串值也可以用字符串面值方式编写,只要将一系列字节序列包含在双引号内即可:

"Hello, 世界"

因为Go语言源文件总是用UTF8编码,并且Go语言的文本字符串也以UTF8编码的方式处理,因此我们可以将Unicode码点也写到字符串面值中。
在一个双引号包含的字符串面值中,可以用以反斜杠\开头的转义序列插入任意的数据。下面的换行、回车和制表符等是常见的ASCII控制代码的转义方式:

\a      响铃
\b      退格
\f      换页
\n      换行
\r      回车
\t      制表符
\v      垂直制表符
\'      单引号 (只用在 '\'' 形式的rune符号面值中)
\"      双引号 (只用在 "..." 形式的字符串面值中)
\\      反斜杠

2、字符串的相关函数
标准库中有四个包对字符串处理尤为重要:bytes(将在下一小节单独记录)、strings、strconv和unicode包。
strings包提供了许多如字符串的查询、替换、比较、截断、拆分和合并等功能。

s := "Hello,World!!!!!"

//Count计算字符串sep在s中的非重叠个数
//func Count(s, sep string) int
n := strings.Count(s, "!")  //n的值为5
n := strings.Count(s, "!!") //n的值为2

//Contains判断字符串s中是否包含子串substr
//func Contains(s, substr string) bool
strings.Contains(s, "Hello")  //结果为true

//ContainsAny判断字符串s中是否包含chars中的任何一个字符
//func ContainsAny(s, chars string) bool
strings.ContainsAny(s, "HJK")  //结果为true

//ContainsRune判断字符串s中是否包含字符r
//Go语言的单引号一般用来表示「rune literal」,即码点字面量
//func ContainsRune(s string, r rune) bool
strings.ContainsRune(s, 'H')  //结果为true

//Index返回子串sep在字符串s中第一次出现的位置,如果找不到,则返回-1
//func Index(s, sep string) int
n := strings.Index(s, "W") //n的值为6

//LastIndex返回子串sep在字符串s中最后一次出现的位置,如果找不到,则返回-1
//func LastIndex(s, sep string) int
n := strings.LastIndex(s, "l")   //n的值为9

//IndexRune返回字符r在字符串s中第一次出现的位置,如果找不到,则返回-1
//func IndexRune(s string, r rune) int
n := strings.IndexRune(s, 'W')   //n的值为6

//IndexAny返回字符串chars中的任何一个字符在字符串s中第一次出现的位置,如果找不到,则返回-1
//func IndexAny(s, chars string) int
n := strings.IndexAny(s, "rd")  //n的值为8

//LastIndexAny返回字符串chars中的任何一个字符在字符串s中最后一次出现的位置如果找不到,则返回-1
//func LastIndexAny(s, chars string) int
n :=  strings.LastIndexAny(s, "rd")  //n的值为10

//Split以sep为分隔符,将s切分成多个子切片:
//func Split(s, sep string) []string
sub_s := strings.Split(s, ",")  //sub_s为[Hello World!!!!!],即sub_s[0]为"Hello", sub_s[1]为"World!!!!!"

//Join将a中的子串连接成一个字符串,用sep分隔
//func Join(a []string, sep string) string
ss := []string{"Monday", "Tuesday", "Wednesday"}
strings.Join(ss, "|")   //结果为Monday|Tuesday|Wednesday

//HasPrefix判断字符串s是否以prefix开头
//func HasPrefix(s, prefix string) bool
strings.HasPrefix(s, "He")  // 结果为true

//HasSuffix判断字符串s是否以prefix结尾:true
//func HasSuffix(s, suffix string) bool
strings.HasSuffix(s, "!!")

//Repeat将count个字符串s连接成一个新的字符串
//func Repeat(s string, count int) string
strings.Repeat(s, 2)

//ToUpper将s中的所有字符修改为其大写格式:HELLO,WORLD!!!!!
//func ToUpper(s string) string
strings.ToUpper(s)

//ToLower将s中的所有字符修改为其小写格式:hello,world!!!!!
//func ToLower(s string) string
strings.ToLower(s)

//Replace返回s的副本,并将副本中的old字符串替换为new字符串
//替换次数为 n 次,如果 n 为 -1,则全部替换
//func Replace(s, old, new string, n int) string
strings.Replace(s, "!", "|", -1)

//EqualFold判断s和t是否相等。忽略大小写,同时它还会对特殊字符进行转换:true
//比如将“ϕ”转换为“Φ”、将“DŽ”转换为“Dž”等,然后再进行比较
 //func EqualFold(s, t string) bool
s1 := "Hello 世界! ϕ DŽ"
s2 := "hello 世界! Φ Dž"
strings.EqualFold(s1, s2)

//Len返回r.i之后的所有数据的字节长度:16
//func (r *Reader) Len() int
r.Len()

//Replace 返回对 s 进行“查找和替换”后的结果
//Replace 使用的是 Boyer-Moore 算法,速度很快
//func (r *Replacer) Replace(s string) string
srp := strings.NewReplacer("Hello", "你好", "World", "世界", "!", "!")
s = "Hello World!Hello World!hello world!"
rst := srp.Replace(s)
fmt.Print(rst) //你好 世界!你好 世界!hello world!

上述函数均参考”http://static.markbest.site/blog/93.html“,还有一些方法没有罗列,如需要,可直接在该网站上查询。

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

//Atoi将string转成int,Itoa将int转成string
fmt.Println(strconv.Atoi("123"))  // 123, nil
fmt.Println(strconv.Atoi("123a")) // 0, strconv.ParseInt: parsing "123a": invalid syntax
fmt.Println(strconv.Itoa(123))    // 123

//format和parse是两组相反的方法,用于string和其它类型之间的相互转化。相关方法有:
fmt.Println(strconv.FormatBool(true))                 // true
fmt.Println(strconv.FormatFloat(3.1415, 'E', -1, 64)) // 3.1415E+00
fmt.Println(strconv.FormatInt(-42, 16))               // -2a
fmt.Println(strconv.FormatUint(42, 16))               // 2a

fmt.Println(strconv.ParseBool("tRue"))        // true <nil>
fmt.Println(strconv.ParseFloat("3.1415", 32)) // 3.1414999961853027 <nil>
fmt.Println(strconv.ParseFloat("3.1415", 64)) // 3.1415 <nil>
fmt.Println(strconv.ParseInt("-42", 10, 32))  // -42 <nil>
fmt.Println(strconv.ParseInt("11011", 2, 32)) // 27 <nil>
fmt.Println(strconv.ParseInt("0xff", 0, 32))  // 255 <nil>
fmt.Println(strconv.ParseUint("42", 16, 32))  // 66 <nil>

上述函数均参考”https://syaning.github.io/go-pkgs/strconv/“,还有一些方法没有罗列,如需要,可直接在该网站上查询。

unicode包提供了IsDigit、IsLetter、IsUpper和IsLower等类似功能,它们用于给字符分类。详细功能,可参考”https://studygolang.com/articles/4358“。

三、byte数组
一个[]byte(s)转换是分配了一个新的字节数组用于保存字符串数据的拷贝,然后引用这个底层的字节数组。可以类比C语言和C++中的char[]数组,在此数组中,可以更多的进行其他操作,比如更改其中的某个元素。
其基本方法和strings包类似,具体参考”https://syaning.github.io/go-pkgs/bytes

四、常量
常量表达式的值在编译期计算,而不是在运行期。每种常量的潜在类型都是基础类型:boolean、string或数字。常量一旦初始化,将不可再一次更改。

const pi = 3.14159 
//声明多个常量
const (
    e  = 2.71828182845904523536028747135266249775724709369995957496696763
    pi = 3.14159265358979323846264338327950288419716939937510582097494459
)

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

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

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

周日将对应0,周一为1,如此等等。
我们同样可以再复杂的常量表达式中使用iota,下面是来自net包的例子,用于给一个无符号整数的最低5bit的每个bit指定一个名字:

type Flags uint

const (
    FlagUp Flags = 1 << iota // FlagUp = 1 <<0       is up     
    FlagBroadcast            // FlagBroadcast  = 1<<1  supports broadcast access capability
    FlagLoopback             // FlagLoopback= 1<<2    is a loopback interface
    FlagPointToPoint         // FlagPointToPoint= 1<<3    belongs to a point-to-point link
    FlagMulticast            //FlagMulticast= 1<<4  supports multicast access capability
)

2、无类型常量
Go语言中可以设置无明确的基础类型的常量,编译器为这些没有明确基础类型的数字常量提供比基础类型更高精度的算术运算。这里有六种未明确类型的常量类型,分别是无类型的布尔型、无类型的整数、无类型的字符、无类型的浮点数、无类型的复数、无类型的字符串。
例如,math.Pi就是一个无类型浮点数常量,但是也可以被转换为float64

const Pi64 float64 = math.Pi
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,734评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,931评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,133评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,532评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,585评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,462评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,262评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,153评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,587评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,792评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,919评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,635评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,237评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,855评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,983评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,048评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,864评论 2 354

推荐阅读更多精彩内容

  • go 变量 Golang 变量声明和初始化比起其他语言要简单一些,并且丰富不少。语法: var identifie...
    邹志全阅读 421评论 0 2
  • 对于所有数据而言,都是由bit组成(二进制数据),但是这些数据在顶层还是可以进一步区分,比如:整型、浮点数、比特数...
    GQ_Lu阅读 283评论 0 0
  • 1. Go语言数据类型 1.1 数据类型分类 Go语言数据类型大致可以分为两类基础类型,其中就包括了我们最常见的一...
    楚江云阅读 677评论 0 0
  • 布尔类型 布尔类型用于表示真假,类型名为bool,只有两个值true和false,占用一个字节宽度,零值为fals...
    imsilence阅读 551评论 0 0
  • 久违的晴天,家长会。 家长大会开好到教室时,离放学已经没多少时间了。班主任说已经安排了三个家长分享经验。 放学铃声...
    飘雪儿5阅读 7,523评论 16 22