主要内容:

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. opencv学习之路(5)、鼠标和滑动条操作

    一.鼠标事件 #include<opencv2/opencv.hpp> #include<iostream> using namespace cv; using namespa ...

  2. 【TensorFlow】tf.nn.max_pool实现池化操作

    max pooling是CNN当中的最大值池化操作,其实用法和卷积很类似 有些地方可以从卷积去参考[TensorFlow]tf.nn.conv2d是怎样实现卷积的? tf.nn.max_pool(va ...

  3. bzoj 1419 Red is good - 动态规划 - 概率与期望

    Description 桌面上有R张红牌和B张黑牌,随机打乱顺序后放在桌面上,开始一张一张地翻牌,翻到红牌得到1美元,黑牌则付出1美元.可以随时停止翻牌,在最优策略下平均能得到多少钱. Input 一 ...

  4. JavaScript中数组的排序方法:1.冒泡排序 2.选择排序

      //1.选择排序: //从小到大排序:通过比较首先选出最小的数放在第一个位置上,然后在其余的数中选出次小数放在第二个位置上,依此类推,直到所有的数成为有序序列. var arr2=[19, 8, ...

  5. minicom支持向串口自动发送命令的功能

    1. 用法 minicom -S <script name> -C <log name> 参数解析: -S: 指定要执行的脚本 -C: 指定输出日志文件名 2. 既然可以指定脚 ...

  6. loj#2510. 「AHOI / HNOI2018」道路 记忆化,dp

    题目链接 https://loj.ac/problem/2510 思路 f[i][a][b]表示到i时,公路个数a,铁路个数b 记忆化 复杂度=状态数=\(nlog^2n\) 代码 #include ...

  7. 【做题】TCSRM601 Div1 500 WinterAndSnowmen——按位考虑&dp

    原文链接https://www.cnblogs.com/cly-none/p/9695526.html 题意:求有多少对集合\(S,T\)满足:\(S \subseteq \{1,2...n \}, ...

  8. Android Studio 快捷键、Debug的使用

    https://blog.csdn.net/q908555281/article/details/49331371 1.快捷键      个人习惯常用快捷键      在Eclipse中常用的快捷键 ...

  9. (zhuan) Attention in Neural Networks and How to Use It

    Adam Kosiorek About Attention in Neural Networks and How to Use It this blog comes from: http://akos ...

  10. 使用路由传参时,query与params的区别!

    query 1:参数会在地址栏显示 2:参数不需要在路由的path后接:args1/:args2 3:获取参数用this.$route.query.args1 params 1:参数需要在路由的pat ...