• golang学习笔记---string && strconv


    1.字符串的组成?
    Golang的字符串都是由单个字节连接起来的,每个字节都是UTF8编码标识的Unicode文本。(不需要在考虑中文不兼容问题)

    2.如何遍历字符串?
    先看一个例子:

    package main
    
    import (
    	"fmt"
    )
    
    func main() {
    	var str = "123"
    	for i := 0; i < len(str); i++ {
    		fmt.Println(str[i])
    	}
    }
    

      

    输出:

    49
    50
    51
    

    和想象中不太一样,接着看下面。

    遍历有两种方式:

    • for i:=0;i<len;i++{}
    • for k,v:=range string {}

    区别在于第一种遍历的事ASCII字符,第二种是Unicode字符,当遇到汉字的时候第一种就会乱码了。这也就解释了前文为啥不是输出123了,需要格式化ASCII码才是我们想看到的。

    第一种 

    package main
    
    import (
    	"fmt"
    )
    
    func main() {
    	var str = "123世界!"
    	for i := 0; i < len(str); i++ {
    		fmt.Printf("%c
    ", str[i])
    	}
    }
    

      

    输出:

    1
    2
    3
    ä
    ¸
    –
    ç
    •
    Œ
    ï
    ¼

    这里乱码原因需要解释下:
    在遍历的时候,ASCII字符只需要一个字节,而非ASCII 字符的可能需要2或者3、4个字节不固定,所以碰到非ASCII 字符的用str[i]来获取一个字节,获取的不全,肯定就乱码了。

    有什么办法解决乱码呢?
    那就是转为rune类型的切片就好了

    package main
    
    import (
    	"fmt"
    )
    
    func main() {
    	var str = "123世界!"
    	strRune := []rune(str)
    	for _, v := range strRune {
    		fmt.Printf("%c
    ", v)
    	}
    }
    

      输出:

    1
    2
    3
    世
    界
    !

    因为在Golang中字符类型实际存储使用rune的。

    第二种 range

    package main
    
    import (
    	"fmt"
    )
    
    func main() {
    	var str = "123世界!"
    	for _, v := range str {
    		fmt.Printf("%c
    ", v)
    	}
    } 

     输出:

    1
    2
    3
    世
    界
    !

    3.如何将字符串与整型互转?
    转换 表达

    import "strconv"
    Atoi : i, err := strconv.Atoi("8888")
    Itoa: s := strconv.Itoa(333)
    Format xxx 转成string字符串
    • FormatBool: func FormatBool(b bool) string
    • FormatFloat: func FormatFloat(f float64, fmt byte, prec, bitSize int) string
    • FormatInt: func FormatInt(i int64, base int) string
    • FormatUint: func FormatUint(i uint64, base int) string

    FormatInt()和FormatUint()有两个参数:第二个参数base指定将第一个参数转换为多少进制,有效值为2<=base<=36。当指定的进制位大于10的时候,超出10的数值以a-z字母表示。例如16进制时,10-15的数字分别使用a-f表示,17进制时,10-16的数值分别使用a-g表示。

    例如:FormatInt(-42, 16)表示将-42转换为16进制数,转换的结果为-2a。

    FormatFloat()参数众多:

    bitSize表示f的来源类型(32:float32、64:float64),会据此进行舍入。

    fmt表示格式:'f'(-ddd.dddd)、'b'(-ddddp±ddd,指数为二进制)、'e'(-d.dddde±dd,十进制指数)、'E'(-d.ddddE±dd,十进制指数)、'g'(指数很大时用'e'格式,否则'f'格式)、'G'(指数很大时用'E'格式,否则'f'格式)。

    prec控制精度(排除指数部分):对'f'、'e'、'E',它表示小数点后的数字个数;对'g'、'G',它控制总的数字个数。如果prec 为-1,则代表使用最少数量的、但又必需的数字来表示f。

    eg:

    s := strconv.FormatBool(true)
    s := strconv.FormatFloat(3.1415, 'E', -1, 64)
    s := strconv.FormatInt(-42, 16)
    s := strconv.FormatUint(42, 16)

    Parse类函数用于转换字符串为给定类型的值:ParseBool()、ParseFloat()、ParseInt()、ParseUint()。
    eg:
    b, err := strconv.ParseBool("true")
    f, err := strconv.ParseFloat("3.1415", 64)
    i, err := strconv.ParseInt("-42", 10, 64)
    u, err := strconv.ParseUint("42", 10, 64)
     

     

    package main
    
    import (
    	"fmt"
    	"strconv"
    )
    
    func main() {
    	var str = "123世界!"
    	for _, v := range str {
    		fmt.Printf("%c
    ", v)
    	}
    
    	s := strconv.FormatBool(true)
    	fmt.Println(s)
    	s = strconv.FormatFloat(3.1415, 'E', -1, 64)
    	fmt.Println(s)
    	s = strconv.FormatInt(-42, 16)
    	fmt.Println(s)
    	s = strconv.FormatUint(42, 8)
    	fmt.Println(s)
    }
    

      输出:

    1
    2
    3
    世
    界
    !
    true
    3.1415E+00
    -2a
    52
    

      

    4.如何改变其中某个字符?
    根据前文我们知道字符有两种,一种是ASCII,一种是Unicode。
    所以需要根据不同的字节数来替换。

    package main
    
    import (
    	"fmt"
    )
    
    func main() {
    	var str = "123世界!"
    	for _, v := range str {
    		fmt.Printf("%c
    ", v)
    	}
    
    	bytes := []byte(str)
    	bytes[1] = 'a'
    	str = string(bytes)
    	fmt.Println(str)
    }
    

    输出:

    1
    2
    3
    世
    界
    !
    1a3世界!
    

      


    如果是想兼容汉字那么使用rune:

    package main
    
    import (
    	"fmt"
    )
    
    func main() {
    	var str = "123世界!"
    	for _, v := range str {
    		fmt.Printf("%c
    ", v)
    	}
    	runes := []rune(str)
    	runes[4] = 'a'
    	str = string(runes)
    	fmt.Println(str)
    }
    

      

    输出:

    1
    2
    3
    世
    界
    !
    123世a!
    

      

    5.如何截取字符串?
    substr := str[n:m] 左开右闭

    6.如何计算长度?

    若全为ASCII字符,则len(str)。
    若存在非ASCII的Unicode字符,则utf8.RuneCountInString(str)。

    package main
    
    import (
    	"fmt"
    	"unicode/utf8"
    )
    
    func main() {
    	var str = "123世界!"
    	fmt.Println(utf8.RuneCountInString(str))
    }
    

      输出:

    6

    7.如何连接字符串?
    提供三种方式:

    第一种(最简单):使用+

    package main
    
    import (
    	"fmt"
    )
    
    func main() {
    
    	str1 := "123"
    	str2 := "世界!"
    	fmt.Println(str1 + str2)
    
    }
    

    输出:

    123世界!



    第二种(最高效):使用字节拼接

    package main
    
    import (
    	"bytes"
    	"fmt"
    )
    
    func main() {
    
    	str1 := "123"
    	str2 := "世界!"
    	var buf bytes.Buffer
    	buf.WriteString(str1)
    	buf.WriteString(str2)
    	fmt.Println(buf.String())
    
    }
    

    输出:

    123世界!


    第三种:使用系统包

    package main
    
    import (
    	"fmt"
    	"strings"
    )
    
    func main() {
    
    	str1 := "123"
    	str2 := "世界!"
    	str := strings.Join([]string{str1, str2}, "")
    	fmt.Println(str)
    
    }
    

    三种连接方式性能测试

    文件:study_test.go

    package main
    
    import (
    	"bytes"
    	"strings"
    	"testing"
    )
    
    func StrPlus1(a []string) string {
    	var s, sep string
    	for i := 0; i < len(a); i++ {
    		s += sep + a[i]
    		sep = " "
    	}
    	return s
    }
    
    func StrPlus2(a []string) string {
    	return strings.Join(a, " ")
    }
    
    func StrPlus3(a []string) string {
    
    	var buf bytes.Buffer
    	var sep = " "
    	for i := 0; i < len(a); i++ {
    		buf.WriteString(a[i])
    		buf.WriteString(sep)
    
    	}
    	return buf.String()
    }
    
    func BenchmarkStrPlus1(b *testing.B) {
    	for i := 0; i < b.N; i++ {
    		StrPlus1([]string{"xxx", "bbb", "aaa"})
    	}
    }
    
    func BenchmarkStrPlus2(b *testing.B) {
    	for i := 0; i < b.N; i++ {
    		StrPlus2([]string{"xxx", "bbb", "aaa"})
    	}
    }
    
    func BenchmarkStrPlus3(b *testing.B) {
    	for i := 0; i < b.N; i++ {
    		StrPlus3([]string{"xxx", "bbb", "aaa"})
    	}
    }
    

    运行压力测试go test -test.bench=".*"

    输出:

  • 相关阅读:
    哈希和不可哈希
    TCP/IP 学习笔记1 浅谈TCP和UDP
    让我们来开发一种更类似人脑的神经网络吧(三)
    关于用CUDA优化三层反传神经网络算法
    让我们来开发一种更类似人脑的神经网络吧(二)
    让我们来开发一种更类似人脑的神经网络吧(六)
    Matlab笔记
    记忆的模式
    让我们来开发一种更类似人脑的神经网络吧(五)
    总结一下感受器官和大脑的通信原理
  • 原文地址:https://www.cnblogs.com/saryli/p/11661576.html
Copyright © 2020-2023  润新知