主要内容:

1. strings和strconv使用
2. Go中的时间和日期类型
3. 指针类型
4. 流程控制
5. 函数详解

1. strings和strconv使用

//strings
. strings.HasPrefix(s string, prefix string) bool:判断字符串s是否以prefix开头 。
. strings.HasSuffix(s string, suffix string) bool:判断字符串s是否以suffix结尾。
. strings.Index(s string, str string) int:判断str在s中首次出现的位置,如果没有
. strings.LastIndex(s string, str string) int:判断str在s中最后出现的位置,如果没有
. strings.Replace(str string, old string, new string, n int)string:字符串替换
. strings.Count(str string, substr string)int:字符串计数
. strings.Repeat(str string, count int)string:重复count次str
. strings.ToLower(str string)string:转为小写
. strings.ToUpper(str string)string:转为大写
. strings.TrimSpace(str string) string:去掉字符串首尾空白字符
strings.Trim(str string, cut string) string:去掉字符串首尾cut字符
strings.TrimLeft(str string, cut string) string:去掉字符串首cut字符
strings.TrimRight(str string, cut string) string:去掉字符串首cut字符
. strings.Fields(str string) []string:返回str空格分隔的所有子串的slice
strings.Split(str string, split string) []string:返回str split分隔的所有子串的slice
. strings.Join(s1 []string, sep string) string:用sep把s1中的所有元素链接起来 //strconv
. strconv.Itoa(i int) string:把一个整数i转成字符串
. strconv.Atoi(str string)(int, error):把一个字符串转成整数

例子:

 package main 

 import (
"fmt"
"strings"
"strconv"
) func main() {
var res bool
//HasPrefix
res = strings.HasPrefix("https://www.baidu.com", "https://") //true
fmt.Printf("%v\n", res)
res = strings.HasPrefix("https://www.baidu.com", "albaba") //false
fmt.Printf("%v\n", res) //HasSuffix
res = strings.HasSuffix("/root/temp/", "/") //true
fmt.Printf("%v\n", res)
res = strings.HasSuffix("/root/temp/", "=") //false
fmt.Printf("%v\n", res) var result int
//Index
result = strings.Index("hahahelloworld", "he") //
fmt.Printf("%v\n", result) //LastIndex
result = strings.LastIndex("hahahelloworldhe", "he") //
fmt.Printf("%v\n", result) var result2 string
//Replace
result2 = strings.Replace("hahahelloworldhe", "ha", "HA", ) //HAhahelloworldhe
fmt.Printf("%v\n", result2)
result2 = strings.Replace("hahahelloworldhe", "ha", "HA", -) //HAHAhelloworldhe
fmt.Printf("%v\n", result2) //Count
result = strings.Count("hahahelloworldhe", "ha") //
fmt.Printf("%v\n", result) //Repeat
result2 = strings.Repeat("ha", ) //hahaha
fmt.Printf("%v\n", result2) //ToLower
result2 = strings.ToLower("heLLo") //hello
fmt.Printf("%v\n", result2) //ToUpper
result2 = strings.ToUpper("hello") //HELLO
fmt.Printf("%v\n", result2) //TrimSpace
result2 = strings.TrimSpace(" hello ") //hello
fmt.Printf("%v\n", result2) //Trim
result2 = strings.Trim("123hello123", "") //hello
fmt.Printf("%v\n", result2) //TrimLeft
result2 = strings.TrimLeft("123hello123", "") //hello123
fmt.Printf("%v\n", result2) //TrimRight
result2 = strings.TrimRight("123hello123", "") //123hello
fmt.Printf("%v\n", result2) var result3 []string
//Fields
result3 = strings.Fields("root temp work")
for i := ; i < len(result3); i++ {
fmt.Printf("%v\n", result3[i])
} //Split
result3 = strings.Split("/root/temp/work", "/")
for i := ; i < len(result3); i++ {
fmt.Printf("%v\n", result3[i])
} //Join
result3 = [] string{"root", "temp", "work"}
result2 = strings.Join(result3, "/") // root/temp/work
fmt.Println(result2) //Itoa
num :=
result2 = strconv.Itoa(num) // root/temp/work
fmt.Printf("%s\n", result2) // 123 //Atoi
str := ""
number, err := strconv.Atoi(str) // root/temp/work
if err != nil {
fmt.Printf("Can not convert %s to int\n", str)
return
}
fmt.Printf("%d\n", number) //
}

example

练习1:判断一个url是否以http://开头,如果不是,则加上http://。
练习2:判断一个路径是否以"/"结尾,如果不是,则加上/。

 package main 

 import (
"fmt"
"strings"
) func urlProcess(url string) string {
res := strings.HasPrefix(url, "http://")
if !res {
url = fmt.Sprintf("http://%s", url)
}
return url
} func pathProcess(path string) string {
res := strings.HasSuffix(path, "/")
if !res {
path = fmt.Sprintf("%s/", path)
}
return path
} func main() {
var (
url string
path string
) fmt.Println("Input url and path >>")
fmt.Scanf("%s%s", &url, &path) url = urlProcess(url)
path = pathProcess(path) fmt.Println("url: ", url)
fmt.Println("path: ", path)
}

练习1和2

练习3:写一个函数返回一个字符串在另一个字符串的首次出现和最后出现位置。

 package main 

 import (
"fmt"
"strings"
) func strIndex(str string, substr string)(int, int) {
var startIndex, endIndex int startIndex = strings.Index(str, substr)
endIndex = strings.LastIndex(str, substr) return startIndex, endIndex
} func main() {
var str, substr string
fmt.Println("Input a string >> ")
fmt.Scanf("%s%s", &str, &substr) start, end := strIndex(str, substr)
if start < {
fmt.Printf("Can not find %s in %s.\n", substr, str)
} else {
fmt.Printf("First find %s in %s %d index.\n", substr, str, start)
} if end < {
fmt.Printf("Can not find %s in %s.\n", substr, str)
} else {
fmt.Printf("Last find %s in %s %d index.\n", substr, str, end)
}
}

练习3

练习4:写一个函数分别演示Replace、Count、Repeat、ToLower、ToUpper的用法。
练习5:写一个函数分别演示TrimSpace、Trim、TrimLeft、TrimRight、Field、Split、以及Join的用法。
练习6:写一个函数分别演示Itoa、Atoi的用法。

2. Go中的时间和日期类型

1. time包
2. time.Time类型,用来表示时间
3. 获取当前时间, now := time.Now()
4. time.Now().Day(),time.Now().Minute(),time.Now().Month(),time.Now().Year()
5. 格式化,fmt.Printf("%02d/%02d%02d %02d:%02d:%02d", now.Year()…)
6. time.Duration用来表示纳秒
7. 一些常量:
    const (
         Nanosecond Duration = 1
         Microsecond = 1000 * Nanosecond
         Millisecond = 1000 * Microsecond
         Second = 1000 * Millisecond
         Minute = 60 * Second
         Hour = 60 * Minute
    )
8. 格式化:
    now := time.Now()
    fmt.Println(now.Format(“02/1/2006 15:04”))
    fmt.Println(now.Format(“2006/1/02 15:04”))
    fmt.Println(now.Format(“2006/1/02”))

练习6:写一个程序,获取当前时间,并格式化成 2017/06/15 08:05:00形式。

 package main 

 import (
"fmt"
"time"
) func main() {
now := time.Now()
fmt.Println(now.Format("02/1/2006 15:04")) // 12/2/2019 18:13
fmt.Println(now.Format("2006/1/02 15:04")) // 2019/2/12 18:13
fmt.Println(now.Format("2006/1/02")) // 2019/2/12
}

练习6

练习7:写一个程序,统计一段代码的执行耗时,单位精确到微秒。

 package main 

 import (
"fmt"
"time"
) func costTime() {
for i := ; i < ; i++ { }
} func main() {
start := time.Now().UnixNano() // ns
costTime()
end := time.Now().UnixNano() fmt.Printf("cost:%d us\n", (end-start)/)
}

练习7

3. 指针类型

1. 普通类型,变量存的就是值,也叫值类型
2. 获取变量的地址,用&,比如: var a int, 获取a的地址:&a
3. 指针类型,变量存的是一个地址,这个地址存的才是值
4. 获取指针类型所指向的值,使用:*,比如:var *p int, 使用*p获取p指向的值

练习8:写一个程序,获取一个变量的地址,并打印到终端。
练习9:写一个函数,传入一个int类型的指针,并在函数中修改所指向的值。在main函数中调用这个函数,并把修改前后的值打印到终端,观察结果。

 package main 

 import (
"fmt"
) func test(num int) {
fmt.Printf("In the test add %v\n", &num)
} func changeNum(num *int) {
*num =
} func main() {
var num int =
fmt.Printf("In the main add %v\n", &num) //In the main add 0xc04203c1d0
test(num) // In the test add 0xc04203c1d8
fmt.Printf("num = %d\n", num) // num = 10
changeNum(&num)
fmt.Printf("num = %d\n", num) //num = 100
}

练习8和9

4. 流程控制

1. If / else分支判断

单个分支

if condition1 {
}

两个分支

if condition1 {
} else {
}

多个分支

if condition1 {
} else if condition2 {
} else if condition3 {
} else {
}

注意:下面这种写法是错误的

if condition1 {
}
else {
}

练习10:写一个程序,从终端读取输入,并转成整数,如果转成整数出错,则输出 "can not convert to int",并返回。否则输出该整数。

 package main 

 import (
"fmt"
"strconv"
) func main() {
var str string
fmt.Println("Input a number >>")
fmt.Scanf("%s", &str)
number, err := strconv.Atoi(str)
if err != nil {
fmt.Printf("Can not convert %s to int\n", str)
return
}
fmt.Printf("%d", number)
}

练习10

2. switch case语句
语法:
       switch var {
           case var1:
           case var2:
           case var3:
           default:
       }

特别注意:go语言中和C语言不一样,在case后面没有break语句。

 switch var {
case var1:
{
语句
break;
} case var2:
{
语句
break;
}
case var3:
{
语句
break;
}
default:
语句
}

C语言写法

写法1:

var num int =
switch num {
case :
fmt.Println("")
case :
fmt.Println("")
case :
fmt.Println("")
default:
fmt.Printf("%d\n", num)
}

写法2:跨越case的fallthrough

var i =
switch i {
case :
fmt.Println("") // 会执行
fallthrough
case :
fmt.Println("") // 由于上面fallthrough 所以会执行
case :
fmt.Println("")
default:
fmt.Println("default")
}

注意:加上fallthrough则当前case语句执行完成之后会紧接着执行相邻的第一条case。

写法3:

var i =
switch i {
//两个case合并
case 0, 1:
fmt.Println("0 or 1")
case :
fmt.Println("")
default:
fmt.Println("def")
}

写法4:

var i =
switch {
case i > && i < :
fmt.Println("i > 0 and i < 10")
case i >= && i < :
fmt.Println("i > 10 and i < 20")
default:
fmt.Println("default")
}

写法5:

switch i := ; {
case i > && i < :
fmt.Println("i > 0 and i < 10")
case i >= && i < :
fmt.Println("i > 10 and i < 20")
default:
fmt.Println("def")
}

注意: i := 15; 后面的分号(;)

练习11:猜数字,写一个程序,随机生成一个0到100的整数n,然后用户在终端,输入数字,如果和n相等,则提示用户猜对了。如果不相等,则提示用户,大于或小于n。

 package main

 import (
"fmt"
"math/rand"
) func main() {
var n int
n = rand.Intn() for {
var input int
fmt.Println("Input your guess >> ")
//注意后面的\n作用,如果没有的话,则输入的数和
fmt.Scanf("%d\n", &input)
flag := false
switch {
case input == n:
fmt.Println("you are right")
flag = true
case input > n:
fmt.Println("bigger")
case input < n:
fmt.Println("less")
} if flag {
break
}
}
}

练习11

3. for 语句

写法1:

for 初始化语句; 条件判断; 变量修改 {
}
//例如
for i := ; i < ; i++ {
fmt.Printf("i=%d\n", i)
}

练习12:写一个程序,在终端打印如下图形。

A
AA
AAA
AAAA
AAAAA
 package main 

 import (
"fmt"
) func main() {
var row int
fmt.Println("Input row number >>")
fmt.Scanf("%d", &row)
for i := ; i < row; i++ {
for j := ; j <= i; j++ {
fmt.Printf("A")
}
fmt.Println()
}
}

练习12

写法2:

for  条件 {
}

例如:下面三个条件为真都是死循环

for i >  {
fmt.Println("i > 0")
} for true {
fmt.Println("i > 0")
} for {
fmt.Println("i > 0")
}

4. for range 语句

写法3:用来遍历数组、slice、map、chan

str := "hello world,中国" //汉字占3个字节
for i, v := range str {
fmt.Printf("index = %d val = %c byteLen = %d\n", i, v, len([] byte(string(v))))
}

5. break、continue语句

package main

import "fmt"

func main() {
str := "hello world,中国"
for i, v := range str {
if i > {
continue
}
if (i > ) {
break
} fmt.Printf("index[%d] val[%c] len[%d]\n", i, v, len([]byte(string(v))))
}
} //输出:
//index[0] val[h] len[1]
//index[1] val[e] len[1]
//index[2] val[l] len[1]

break 语句可以结束 for、switch 和 select 的代码块。break 语句还可以在语句后面添加标签,表示退出某个标签对应的代码块,标签要求必须定义在对应的 for、switch 和 select 的代码块上。例如:

package main
import "fmt"
func main() {
OuterLoop:
for i := ; i < ; i++ {
for j := ; j < ; j++ {
switch j {
case :
fmt.Println(i, j)
break OuterLoop
case :
fmt.Println(i, j)
break OuterLoop
}
}
}
} //输出 说明第10行的break OuterLoop直接跳出外层循环
//0 2

continue 语句可以结束当前循环,开始下一次的循环迭代过程,仅限在 for 循环内使用。在 continue 语句后添加标签时,表示开始标签对应的循环。例如:

package main
import "fmt"
func main() {
OuterLoop: //代码说明:第 10 行将结束当前循环,开启下一次的外层循环,而不是第 10 行的内循环。
for i := ; i < ; i++ {
for j := ; j < ; j++ {
switch j {
case :
fmt.Println(i, j)
continue OuterLoop
}
}
}
} //输出:
//0 2
//1 2

6. goto 和 label 语句

goto 语句通过标签进行代码间的无条件跳转。goto 语句可以在快速跳出循环、避免重复退出上有一定的帮助。Go 语言中使用 goto 语句能简化一些代码的实现过程。

package main

func main() {
i :=
HERE:
print(i)
i++
if i == {
return
}
goto HERE
} //输出:
//

 5. 函数

1. 声明语法:func 函数名 (参数列表) [(返回值列表)] {}

//无参数,无返回值
func add() {
} //有参数,无返回值
func add(a int, b int) {
} //有参数,一个返回值
func add(a int, b int) int {
} //有参数,两个返回值
func add(a int, b int) (int, int) {
} //有参数,两个返回值
func add(a, b int) (int, int) {
}

2. golang函数特点:
    a. 不支持重载,一个包不能有两个名字一样的函数
    b. 函数是一等公民,函数也是一种类型,一个函数可以赋值给变量

 package main

 import "fmt"

 func add(a, b int) int {
return a + b
} func main() {
c := add //将函数add的地址赋值给变量c
fmt.Println(c) //0x4888e0 sum := c(, )
fmt.Println(sum)
// if (c == add) { //invalid operation: c == add (func can only be compared to nil)
// fmt.Println("c equal add")
// }
}

函数赋值给变量

c. 匿名函数

 package main

 import "fmt"

 var (
//add存放的是匿名函数的地址
add = func(a int, b int) int {
return a + b
} //sub_res存放的是匿名函数执行的结果100
sub_res = func(a int, b int) int {
return a - b
}(, )
) func test(a, b int) int {
//mult存放的是匿名函数的地址
mult := func(m int, n int) int {
return m*n
}
return mult(a, b)
} func main() {
fmt.Println(add(, )) //
fmt.Println(sub_res) //
fmt.Println(test(, )) //
}

匿名函数

d. 多返回值

使用type定义函数类型: type type_name func 函数名 (参数列表) [(返回值列表)],例如:

 package main

 import "fmt"

 //定义函数类型
type add_func func(int, int) int func add(a, b int) int {
return a + b
} // error 因为上面定义的函数类型add_func接收两个参数,下面定义三个参数。
// func add(a, b, c int) int {
// return a + b
// } func sub(a, b int) int {
return a - b
} func operator(op add_func, a int, b int) int {
return op(a, b)
} func main() {
c := add
fmt.Println(c)
sum := operator(c, , )
fmt.Println(sum) // res := operator(sub, , )
fmt.Println(res) //-100
}

定义函数类型

3. 函数参数传递方式:
    1). 值传递
    2). 引用传递
    注意1:无论是值传递,还是引用传递,传递给函数的都是变量的副本,不过,值传递是值的拷贝。引用传递是地址的拷贝,一般来说,地址拷贝更为高效。而值拷贝取决                   于拷贝的对象大小,对象越大,则性能越低。
    注意2:map、slice、chan、指针、interface默认以引用的方式传递。

4. 命名返回值的名字

 package main 

 import "fmt"

 func add(a, b int) (sum int) {
sum = a + b
return
} // 等价于
// func add(a, b int) int {
// sum = a + b
// return sum
// } func calc(a, b int) (sum int, avg int) {
sum = a + b
avg = (a +b)/
return
} // 等价于
// func calc(a, b int) (int, int) {
// sum = a + b
// avg = (a +b)/2
// return sum, avg
// } func main() {
add_res := add(, )
fmt.Println(add_res) //
sum, avg := calc(, )
fmt.Println(sum) //
fmt.Println(avg) //
}

命名返回值的名字

5. _标识符,用来忽略返回值

 package main 

 import "fmt"

 func calc(a, b int) (sum int, avg int) {
sum = a + b
avg = (a +b)/
return
} func main() {
sum, _ := calc(, )
fmt.Println(sum) //
}

忽略返回值

6. 可变参数

注意:其中arg是一个slice,通过len(arg)来判断传递参数的个数,通过arg[index]依次访问所有参数。

//0个或多个参数
func add(arg…int) int {
} //1个或多个参数
func add(a int, arg…int) int {
} //2个或多个参数
func add(a int, b int, arg…int) int {
}

练习14:写一个函数add,支持1个或多个int相加,并返回相加结果。
练习15:写一个函数concat,支持1个或多个string相拼接,并返回结果。

 package main

 import "fmt"

 func add(a int, arg ...int) int {
var sum int = a
for i := ; i < len(arg); i++ {
sum += arg[i]
} return sum
} func concat(a string, arg ...string) (result string) {
result = a
for i := ; i < len(arg); i++ {
result += arg[i]
} return
} func main() {
sum := add(, , , , )
fmt.Println(sum) // res := concat("hello", " ", "world")
fmt.Println(res) //hello world
}

可变参数

7. defer用途
    1). 当函数返回时,执行defer语句。因此,可以用来做资源清理。
    2). 多个defer语句,按先进后出的方式执行。
    3). defer语句中的变量,在defer声明时就决定了。

 package main 

 import "fmt"

 func test() {
i :=
defer fmt.Println(i)
i++
return
} func main() {
test() //
}

example1

 package main 

 import "fmt"

  func test() {
for i := ; i < ; i++ {
defer fmt.Printf("%d ", i)
}
} func main() {
test() // 4 3 2 1 0
}

example2

defer几个常用用途:

(1). 关闭文件句柄

 func read() {
file := open(filename)
defer file.Close() //文件操作
}

关闭文件句柄

(2). 锁资源释放

 func read() {
mc.Lock()
defer mc.Unlock()
//其他操作
}

锁资源释放

(3). 数据库连接释放

 func read() {
conn := openDatabase()
defer conn.Close()
//其他操作
}

数据库连接释放

练习:

1.编写程序,在终端输出九九乘法表。

 package main 

 import "fmt"

 func mutil() {
for i := ; i <= ; i++ {
for j := ; j <= i; j++ {
fmt.Printf("%d*%d=%d\t", i, j, i*j)
}
fmt.Printf("\n")
}
} func main() {
mutil()
}

练习1

2.一个数如果恰好等于它的因子之和,这个数就称为“完数”。例如6=1+2+3编程找出1000以内的所有完数。

 package main 

 import "fmt"

 func isPerfNum(num int) bool {
res :=
for i := ; i < num; i++ {
if num % i == {
res += i
}
} return res == num
} func process(n int) {
for i := ; i <= n; i++ {
if isPerfNum(i) {
fmt.Println(i)
}
}
} func main() {
var num int
fmt.Println("Input a number >> ")
fmt.Scanf("%d", &num)
process(num)
}

练习2

3.输入一个字符串,判断其是否为回文。回文字符串是指从左到右读和从右到左读完全相同的字符串。

 package main 

 import (
"fmt"
) func isPalindNum(str string) bool {
flag := true
for i := ; i <= int(len(str)/); i++ {
if str[i] != str[len(str)-i-] {
flag = false
break
}
} return flag
} func main() {
var str string
fmt.Println("Input a string >> ")
fmt.Scanf("%s", &str)
if isPalindNum(str) {
fmt.Printf("%s is a palindrome number.", str)
}
}

练习3 V1(无法处理汉字回文数)

 package main 

 import (
"fmt"
) func isPalindNum(str string) bool {
temp := [] rune(str) //注意这块的处理
flag := true
for i := ; i <= int(len(temp)/); i++ {
if temp[i] != temp[len(temp)-i-] {
flag = false
break
}
} return flag
} func main() {
var str string
fmt.Println("Input a string >> ")
fmt.Scanf("%s", &str)
if isPalindNum(str) {
fmt.Printf("%s is a palindrome number.", str)
}
}

练习3 V2(完整版)

4.输入一行字符,分别统计出其中英文字母、空格、数字和其它字符的个数。

 package main 

 import (
"fmt"
"os"
"bufio"
) func count(str string) (charCount, spaceCount, numberCount, otherCount int) {
t := [] rune(str)
for _, v := range t {
switch {
case v >= 'A' && v <= 'Z':
fallthrough
case v >= 'a' && v <= 'z':
charCount++
case v == ' ':
spaceCount++
case v >= '' && v <= '':
numberCount++
default:
otherCount++
}
}
return
} func main() {
reader := bufio.NewReader(os.Stdin)
result, _, err := reader.ReadLine()
if err != nil {
fmt.Println("read from console err:", err)
return
}
cc, sc, nc, oc := count(string(result)) //注意:result为type []byte,因此需要强制转换为string类型
fmt.Printf("charCount = %d, spaceCount = %d, numberCount = %d, otherCount = %d", cc, sc, nc, oc)
}

练习4

5. 计算两个大数相加的和,这两个大数会超过int64的表示范围。

 package main 

 import (
"fmt"
"os"
"bufio"
"strings"
) func add(str1, str2 string) (result string) {
var left int = //进位 if len(str1) == || len(str2) == {
result = ""
return
} index1 := len(str1) -
index2 := len(str2) -
//处理重合部分
for index1 >= && index2 >= {
c1 := str1[index1] - ''
c2 := str2[index2] - '' sum := int(c1) + int(c2) + left
if sum >= {
left =
} else {
left =
} c3 := (sum%) + ''
result = fmt.Sprintf("%c%s", c3, result) index1--
index2--
} //处理str1长度大于str2情况
for index1 >= {
c1 := str1[index1] - '' sum := int(c1) + left
if sum >= {
left =
} else {
left =
} c3 := (sum%) + ''
result = fmt.Sprintf("%c%s", c3, result) index1--
} //处理str1长度小于str2情况
for index2 >= {
c2 := str2[index2] - '' sum := int(c2) + left
if sum >= {
left =
} else {
left =
} c3 := (sum%) + ''
result = fmt.Sprintf("%c%s", c3, result) index2--
} //处理str1长度等于str2情况
if left == {
result = fmt.Sprintf("1%s", result)
}
return
} func main() {
fmt.Println("please input a+b >>")
//从console端读取数据
reader := bufio.NewReader(os.Stdin)
result, _, err := reader.ReadLine()
if err != nil {
fmt.Println("read from console err:", err)
return
} //获取加数与被加数
strSlice := strings.Split(string(result), "+")
if len(strSlice) != {
fmt.Println("please input a+b")
return
} //去除左右空格
str1 := strings.TrimSpace(strSlice[])
str2 := strings.TrimSpace(strSlice[])
fmt.Println(add(str1, str2))
}

练习5

补充:rune数据类型

例1:

 package main

 import "fmt"

 func main() {

     var str = "hello 你好"
fmt.Println("len(str):", len(str)) //len(str): 12
}

example

为何输出12?

golang中string底层是通过byte数组实现的。中文字符在unicode下占2个字节,在utf-8编码下占3个字节,而golang默认编码是utf-8。因此输出12。

例2:

 package main

 import "fmt"

 func main() {

     var str = "hello 你好"
fmt.Println("len(str):", len(str)) //len(str): 12 temp := [] rune(str)
fmt.Println("len(temp):", len(temp)) //len(temp): 8
}

example2

现在来看rune数据类型官方解释:

rune is an alias for int32 and is equivalent to int32 in all ways. It is used, by convention, to distinguish character values from integer values.

rune是int32的别名,几乎在所有方面等同于int32,它用来区分字符值和整数值。type rune = int32。

如果我们预期想得到一个字符串的长度,而不是字符串底层占得字节长度,该怎么办?

例3:

 package main

 import (
"fmt"
"unicode/utf8"
) func main() { var str = "hello 你好"
// 方法1:
//golang中的unicode/utf8包提供了用utf-8获取长度的方法
fmt.Println("RuneCountInString:", utf8.RuneCountInString(str)) //RuneCountInString: 8 //方法2:
//通过rune类型处理unicode字符
temp := [] rune(str)
fmt.Println("rune:", len(temp)) //rune: 8
}

example3

例4:

 package main

 import (
"fmt"
) func main() { var str = "hello 你好"
for i := ; i < len(str); i++ {
fmt.Println(str[i])
} fmt.Println("--------") temp := [] rune(str)
for i := ; i < len(temp); i++ {
fmt.Println(temp[i])
}
} //输出结果
// 104
// 101
// 108
// 108
// 111
// 32
// 228
// 189
// 160
// 229
// 165
// 189
// --------
// 104
// 101
// 108
// 108
// 111
// 32
// 20320
//

example4

总结:

golang中一个byte数据类型与rune相似,它们都是用来表示字符类型的变量类型。它们的不同在于:
(1). byte 等同于int8,常用来处理ascii字符。
(2). rune 等同于int32,常用来处理unicode或utf-8字符。

参考文献:

  • https://www.jianshu.com/p/4fbf529926ca

Go语言学习之3 流程控制、函数的更多相关文章

  1. R语言学习 第四篇:函数和流程控制

    变量用于临时存储数据,而函数用于操作数据,实现代码的重复使用.在R中,函数只是另一种数据类型的变量,可以被分配,操作,甚至把函数作为参数传递给其他函数.分支控制和循环控制,和通用编程语言的风格很相似, ...

  2. PYTHON 学习笔记2 流程控制工具以及函数定义、匿名函数

    前言 在上一节的学习中.已经介绍了几种基本类型.包括字符串的定义,以及字符串中索引.切片.字符串拼接的使用方法.以及基本的整形数据运算.一些之前都没有了解过的运算符.比如 ** 乘方 //整数除法等. ...

  3. Python学习笔记 - day4 - 流程控制

    Python流程控制 Python中的流程控制主要包含两部分:条件判断和循环. Python的缩进和语法 为什么要在这里说缩进和语法,是因为将要学习的条件判断和分支将会涉及到多行代码,在java.c等 ...

  4. golang(3):strings和strconv使用 & 时间和日期类型 & 指针类型 & 流程控制 & 函数

    strings和strconv使用 . strings.HasPrefix(s string, prefix string) bool: // 判断字符串s是否以prefix开头 . . string ...

  5. 大一C语言学习笔记(5)---函数篇-定义函数需要了解注意的地方;定义函数的易错点;详细说明函数的每个组合部分的功能及注意事项

    博主学习C语言是通过B站上的<郝斌C语言自学教程>,对于C语言初学者来说,我认为郝斌真的是在全网C语言学习课程中讲的最全面,到位的一个,这个不是真不是博主我吹他哈,大家可以去B站去看看,C ...

  6. shell流程控制&函数

    条件 if-then-elif-then-fi if的条件部分经常使用test EXPRESSION或[ EXPRESSION ]实现,test的用法可以参见test if 条件1 #if 条件1;t ...

  7. lishell学习之路:流程控制(case)

    流程控制case语句: 介绍:多分支case条件语句 1.case语句和if..elif..else语句一样都是多分支条件语句,不过和if多分支条件语句不同的是,case语句只能判断一种条件关系,而i ...

  8. 【原】Java学习笔记005 - 流程控制

    package cn.temptation; public class Sample01 { public static void main(String[] args) { // 程序的流程控制(流 ...

  9. 【C语言 基础】什么流程控制?

    流程控制就是控制程序执行的顺序 流程控制的分类: 1.顺序执行 2.选择执行 定义 某些代码可能执行也可能不执行,有选择的执行某些代码 3.循环执行

随机推荐

  1. 监控mysql状态脚本

    监控mysql状态, 发现宕后, 自动重启, 每秒检查一次. check.sh #!/bin/bash while [ true ]; do /bin/sleep 1 sh mysql_status. ...

  2. 前缀和与差分之IncDec sequence

    参考链接:https://blog.csdn.net/hzk_cpp/article/details/80407014 题目链接:https://www.acwing.com/problem/cont ...

  3. 如果此表在它的 ChildRelation 集合中不是父表,则不能将关系添加到该集合中。

    今天遇到这个问题头都大了,百度上也没找到解决方案,就自己在哪里沉思................ 终于皇天不负有心人,被我解决了! 这是调用ChildRelations.Add(“名字”,“父级”, ...

  4. ODAC(V9.5.15) 学习笔记(四)TCustomDADataSet(5)

    7.其他 名称 类型 说明 FindKey 类似于BDE的相关功能,在当前数据集中查找指定的记录 FindNearest 移动游标到最符合查找要求的第一条记录处 FindMacro 当前数据集中是否存 ...

  5. shell编程(三)之条件判断(if语句)

    练习:写一个脚本判断当前系统上是否有用户的默认shell为bash: 如果有,就显示有多少个这类用户:否则,就显示没有这类用户: #!/bin/bash # grep '\<bash$' /et ...

  6. [POJ 2386] Lake Counting(DFS)

    Lake Counting Description Due to recent rains, water has pooled in various places in Farmer John's f ...

  7. Java基础【冒泡、选择排序、二分查找】

    冒泡排序的思路就是前一个和后一个进行比较,如果大的就交换位置   大的数字后浮 如   12      8    5     31 第一轮   8   5   12   31 第二轮   5   8 ...

  8. 【ASP.NET】System.Web.Routing - StopRoutingHandler Class

    Provides a way to specify that ASP.NET routing should not handle requests for a URL pattern. ex: rou ...

  9. java泛型的作用和好处

    转载于:https://blog.csdn.net/u012760183/article/details/52092692 之前参加面试的时候遇到面试官问泛型的作用,只是说了大概自己的理解, 在此转载 ...

  10. mybatis配置文件resultMap标签的使用

    本文为博主原创,未经允许不得转载: resultMap标签是为了映射select查询出来结果的集合,其主要作用是将实体类中的字段与 数据库表中的字段进行关联映射. 注意:当实体类中的字段与数据库表中的 ...