• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

go语言之字符串、指针、数组、切片、结构struct、面向对象

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

一: 字符串

概述:
Go 语言将字符串作为 种原生的基本数据类型,字 符串的初始化可以使用字符串字面量。
(1)字符串是常量,可以通过类 数组 索引访问其字节单元,但是不能修改某个字节的值
(2)宇符串转换为切片[]byte( 要慎用,尤其是当数据量较大时(每转换一次都需复制内容)
a := ” hello, world !” 
b : = []byte (a) 
(3)字符串尾部不包含 NULL 字符
(4)字符串类型底层实现是一个二元的数据结构,一个是指针指向字节数组的起点,另一个是长度

(5)基于字符串创建的切片和原字符串指向相同的底层字符数组 一样不能修改 对字符
串的切片操作返回的子串仍然是由in ,而非 slice

a := ” hello, world !
b :=a[0:4 ]
c :=a [1:2] 
d :=a [:4) 
(6 )字符串和切片的转换字符串可以转换为字节数组,也可以转换为 Unicode 的字数组。
(7 )字符串的运算。

示例:

package main

import (
    "bytes"
    "fmt"
    "strconv"
    "strings"
    "time"
)

func main() {
fmt.Println("字符串测试")

fmt.Println("字符串转化")
//获取程序运行的操作系统平台下 int 类型所占的位数,如:strconv.IntSize。
//strconv.IntSize

fmt.Println("将字符串转换为 int 型。")
var trastr01 string = "100"
traint01, err_tra := strconv.Atoi(trastr01)
if err_tra != nil {
fmt.Println(err_tra)
} else {
fmt.Println(traint01)
}
fmt.Println("将字符串转换为 float64 型")
var trastr02 string = "100.55"
trafloat01, err_float := strconv.ParseFloat(trastr02, 10)
if err_float != nil {
fmt.Println(err_float)
} else {
fmt.Println(trafloat01)
}
trastr03 := strconv.Itoa(99)
fmt.Println("int 转字符安 " + trastr03)

var str01 string = "hello,world"
str02 := "你好,世界"
fmt.Println(str01)
fmt.Println(str02)

//

//字符串比较
com01 := strings.Compare(str01, str02)
if com01 == 0 {
fmt.Println("相等")
} else {
fmt.Println("不相等 " + string(com01))
}
fmt.Println(com01)

//查找 包含
var isCon bool = strings.Contains(str01, "hello")
fmt.Println(isCon) //true

//查找位置
var theIndex int = strings.Index(str01, ",")
fmt.Println(theIndex)                     //5
fmt.Println(strings.Index(str01, "haha")) //不存在返回-1

lastIndex := strings.LastIndex(str01, "o")
fmt.Println("在字符串中最后出现位置的索引 " + strconv.Itoa(lastIndex)) //7
//-1 表示字符串 s 不包含字符串

//统计给定子串sep的出现次数, sep为空时, 返回1 + 字符串的长度
fmt.Println(strings.Count("cheeseeee", "ee")) // 3
fmt.Println(strings.Count("five", ""))        // 5

// 重复s字符串count次, 最后返回新生成的重复的字符串
fmt.Println("hello " + strings.Repeat("world ", 10))

fmt.Println("替换")
// 在s字符串中, 把old字符串替换为new字符串,n表示替换的次数,小于0表示全部替换
var str03 string = "/Users//Documents/GOPatch/src/MyGO/config/TestString/"
str04 := strings.Replace(str03, "/", "**", -1)
str05 := strings.Replace(str03, "/", "**", 4)

fmt.Println(str04) //**Users****Documents**GOPatch**src**MyGO**config**TestString**
fmt.Println(str05) //**Users****Documents**GOPatch/src/MyGO/config/TestString/

fmt.Println("删除字符串的开头和尾部")
fmt.Println("删除两头的/ = " + strings.Trim(str03, "/"))      //Users//Documents/GOPatch/src/MyGO/config/TestString
fmt.Println("删除左边的/ =  " + strings.TrimLeft(str03, "/")) //Users//Documents/GOPatch/src/MyGO/config/TestString/
//还有 TrimRight

str06 := strings.TrimSpace(" hello hao hao hao ")
fmt.Println("删除开头末尾的空格 =" + str06) //'hello hao hao hao'

fmt.Println("大小写")
str07 := "hello hao hao hao"
fmt.Println(strings.Title(str07))                  //Hello Hao Hao Hao
fmt.Println(strings.ToLower(" Hello Hao Hao Hao")) // hello hao hao hao
fmt.Println(strings.ToUpper(str07))                //HELLO HAO HAO HAO

//前缀 后缀
fmt.Println(strings.HasPrefix("Gopher", "Go")) // true
fmt.Println(strings.HasSuffix("Amigo", "go"))  // true

fmt.Println("字符串分割")
fieldsStr := "  hello   it's  a  nice day today    "
//根据空白符分割,不限定中间间隔几个空白符
fieldsSlece := strings.Fields(fieldsStr)
fmt.Println(fieldsSlece) //[hello it's a nice day today]

for i, v := range fieldsSlece {
fmt.Printf("下标 %d 对应值 = %s \n", i, v)
}
for i := 0; i < len(fieldsSlece); i++ {
fmt.Println(fieldsSlece[i])
}

//根据特定字符分割
slice01 := strings.Split("q,w,e,r,t,y,", ",")
fmt.Println(slice01)      //[q w e r t y ]
fmt.Println(cap(slice01)) //7  最后多个空""
for i, v := range slice01 {
fmt.Printf("下标 %d 对应值 = %s \n", i, v)
}

//拼接
//Join 用于将元素类型为 string 的 slice, 使用分割符号来拼接组成一个字符串:
var str08 string = strings.Join(fieldsSlece, ",")
fmt.Println("Join拼接结果=" + str08) //hello,it's,a,nice,day,today

fmt.Println("------------对比字符串拼接效率----------------")
var buffer bytes.Buffer

start := time.Now()
for i := 0; i < 100000; i++ {
buffer.WriteString("test is here\n")
}
buffer.String() // 拼接结果
end := time.Now()
fmt.Println("Buffer time is ", end.Sub(start).Seconds())

start = time.Now()
str := ""
for i := 0; i < 100000; i++ {
str += "test is here\n"
}
end = time.Now()
fmt.Println("+= time is ", end.Sub(start).Seconds())

start = time.Now()
var sl []string
for i := 0; i < 100000; i++ {
sl = append(sl, "test is here\n")
}
strings.Join(sl, "")
end = time.Now()
fmt.Println("Join time is", end.Sub(start).Seconds())
/*
   Buffer time is  0.00388283
   += time is  11.730007558
   Join time is 0.016644653
*/

}

复合类型数据结构

基本复合数据类型有:指针、数组、切片、字典( map )、通道、结构和接口

* pointerType   //指针类型使用*后面跟其指向的类型名
[n]  elementType  ///数纽类型使用[]后面跟数纽元素类型来表示, n表示该数组的长度
[] elementType  //切片类型使用[] 后面跟切片元素类型来表示
map [keyType] valueType //map类型使用map[键类型]值类型来表示
chan valueType  //通道使用chan后面跟通道元素类型表示
interface{   //接口类型 interface{} 将各个方法括起来
    method1(inputParams)(returnParams)
    method2(inputParams) (returnParams)
)

二:指针

概述:
指针声明类型为*T,多指针为**T
通过变量名前加&来获取变量的地址

1)在赋值语句中,*T出现在”=“ 左边表示声明,*T出现在”=“右边表示取指针指向的值(varName)

var a=11
p := &a   //*p和a的值都是11

2)结构体指针访问结构体字段然仍使用”.“ 点操作符

import "fmt"

type User struct {
    name  string
    age  int
}
func main(){
    andes := User{
        name: "andes",
        age: 18,
    }
    p := &andes
    fmt.Println(p.name)  //p.name 通过“.”操作符访问成员变量
}

 

 指针的使用

package main

import "fmt"

func main() {
   // 声明变量
   var a int = 20
   // 声明指针
   var ip *int
   // 指针变量的存储
   ip = &a
   fmt.Printf("a变量地址是:%x\n", &a)
   //指针变量存储的地址
   fmt.Printf("ip变量存储的指针地址:%x\n", ip)
   //使用指针访问值
   fmt.Printf("*ip变量的值:%d\n", *ip)
}

3)go不支持指针运算

 Go 由于支持垃圾回收,如果支持指针运算,则会给垃圾回收的 现带来很多不

a := 1234 
P := &a 
p++       // 不允许,报 non-numeric type *int 错误

 4)函数中允许返回局部变量的地址

Go 编译器使用“战逃逸 机制将这种局部变量的空间分配在堆上

package main

import "fmt"

func sum (a , b int) *int {
    sum := a + b
    return &sum      //允许, sum会分配在heap上
}
func main(){
    fmt.Println(sum(1,2)) //打印内存地址
}

指针练习

 程序获取一个int变量num的地址并打印
 将num的地址赋给指针ptr,并通过ptr去修改num的值
package main
import "fmt"
func main(){
	//定义变量
	var num int =10
	fmt.Println(&num)
	//定义指针
	var ptr *int
	//指针赋值
	ptr = &num
	//根据指针修改值
	*ptr=20
	fmt.Println(num)
}

三: 数组

概述:
数组的类型名是 [n]emetType ,其中n是数组长度, elementType 是数组元素类型
数组一般在 创建时通过字面量初始化,单独声明一个数组类型变量而不进行初始化是没有意义的。

1)数组初始化

a : = [3]int {123} //指定长度和初始化字面量
a : = [ . . . ]int{l , 2 , 3} //不指定长度,但是由后面的初始 列表数量来确定其长度
a : = [3]int{l : l , 2 : 3)  // 指定总长度,并通过索引值进行初始化,没有初始化元素时使用类型默认值
a : =[ ...}int{l :1,2 : 3)  //不指定总长度,通过索引值进行初始化,数组长度由最后一个索引值确定,没有指定索引的元 被初始化为类型的零值

2)数组的特点:

1 )数组创建完长度就固定了,不可以再追加元素。
2 )数组是值类型的,数组赋值或作为函数参数都是值拷贝。
3 )数组长度是数组类型的组成部分,[10]int 和[20]int 表示不同的类型。
4 )可以根据数组创建切片

3) 数组相关操作

  1 数组元素的访问

package main

import "fmt"

func main()  {
    a :=[...]int{1,2,3}
    b := a[0]
    for i,v :=range a{
        fmt.Println(i,v)
        fmt.Println(b)
    }
}

  2 数组切片的长度

package main

import "fmt"

func main(){
    a := [...]int{1,2,3}
    alengh :=len(a)
    for i :=0; i<alengh; i++{ 
        fmt.Println(a)       //[1 2 3]
        fmt.Println(alengh)   //3   数组长度
        fmt.Println(i)      //2  索引值
    }
}

四:切片

概述:
Go 语言的数组的定长性和值拷贝限制了其使用场景, Go 提供了另一种数据类型 lic (中文为切片),
这是 种变长数组,其数据结构中有指向数组的指针,所以是 种引用类型
package main

import "unsafe"

func main(){
	type slice struct {
		arry unsafe.Pointer  
		len int   
		cap int     //cap()函数返回的是数组切片分配的空间大小
	}
}

Go 为切片维护 个元素一一指向底层数组的指针、切片的元素数量和底层数组的容量。

切片的相关操作

 

1  切片的创建:

  1)由数组创建

语法:
array[b:c],array表示数组名;b表示开始索引,可以不指定,默认是0;c表示结束索引,可以不指定,默认是len(array),数组长度,
package main
import (
    "fmt"
)
func main(){
    //创建有7个int类型元素的数组
    var array  = [...]int{0,1,2,3,4,5,6}
    s1  := array[0:4]
    s2  := array[:4]
    s3  := array[2:]
    fmt.Println("%v\n",s1)   // [0 1 2 3]
    fmt.Println("%v\n",s2)    // [0 1 2 3]
    fmt.Println("%v\n",s3)    // [2 3 4 5 6]
}

  2)通过内置函数make创建切片

  注意:由make创建的切片各元素被默认初始化为切片元素类型的零值

package main

import "fmt"

func main(){
    //len=10,cap=10  创建数组a
    a := make([]int,10)
    //len=10,cap=5   创建数组b
    b := make([]int,10,15)
    fmt.Printf("%v\n",a)   //[0 0 0 0 0 0 0 0 0 0]
    fmt.Printf("%v\n",b)   //[0 0 0 0 0 0 0 0 0 0] 
}

  注意:直接声明切片类型变量是没有意义的

func main(){
    var a  []int
    fmt.Printf("%v\n",a)   //结采为 []
}

  此时切片a底层的数据结构

   3)切片支持的操作

1  内置函数 len()返回切片长度
2  内置函数 cap()返回切片底层数组容量。
3  内置函数 ppend()对切片追加元素。
4  内置函数 copy() 用于 一个切片
package main

import (
    "fmt"
)

func main()  {
    a := [...]int{0,1,2,3,4,5,6}
    b := make([]int,2,4)
    c := a[0:3]
    fmt.Println(b)  //[0 0]
    fmt.Println(len(b))  //2
    fmt.Println(cap(b))  // 4
    b = append(b,1) //切片尾部追加元素 1
    fmt.Println(b)          //[0 0 1]
    fmt.Println(len(b))    //3
    fmt.Println(c)       //[0 1 2]
    fmt.Println(cap(b))   //4

    b = append(b,c...)
    fmt.Println(b)    //[0 0 1 0 1 2]
    fmt.Println(len(b))   //6
    fmt.Println(cap(b))  //8

    d := make([]int,2,2)
    copy(d,c)       //copy只会复制d和c中长度最小的
    fmt.Println(d)    //[0 1]
    fmt.Println(len(d))  //2
    fmt.Println(cap(d))  //2
}

  示例二

package main

import "fmt"

func main() {
   // 定义数组
   arr := [...]int{0,1,2,3,4,5,6,7}
   // 切片取值
   fmt.Println("arr[2:6]=",arr[2:6])
   fmt.Println("arr[:6]=",arr[:6])
   fmt.Println("arr[2:]=",arr[2:])
   fmt.Println("arr[:]=",arr[:])
}

  l内建函数append():向切片尾部添加数据

package main

import "fmt"

func main() {
    //空切片
    var s1 []int
    s1=append(s1,2,3)
    s1=append(s1, 4,5,6)
    fmt.Println("s1=" ,s1)      //s1= [2 3 4 5 6]
    //创建指定大小的切片
    s2 := make([]int,5)   //创建长度为5的并初始化为0的切片
    s2 =append(s2,6)
    fmt.Println(s2)      //[0 0 0 0 0 6]
    //创建并初始化切片
    s3 := []int{1,2,3}
    s3 =append(s3,4,5)
    fmt.Println(s3)   //[1 2 3 4 5]
}

  示例2  

package main

import (
    "fmt"
)

func main() {
    //1 go 语言切片是对原数组的映射,并没有创建一个真正的切片
    //定义数组
    arr :=[...]int{0,1,2,3,4,5,6,7}
    //取切片
    s1 :=arr[2:6]
    fmt.Println(s1)  //[2 3 4 5]

    s2 := s1[3:5]
    fmt.Println(s2)  //[5 6]
    s3 := append(s2,10)
    fmt.Println(s3)  //[5 6 10]
    s4 :=append(s3,11)
    fmt.Println(s4) //[5 6 10 11]
    s5 :=append(s4,12)
    fmt.Println(s5)   //[5 6 10 11 12]
}

  内置函数copy()

package main

import "fmt"

func main() {
    //go语言切片是对原数组的映射,并灭有创建一个真正的切片
    //定义数组
    data := [...]int{0,1,2,3,4,5,6,7,8,9}
    //取切片 8,9
    s1 := data[8:]
    s2 := data[:5]
    //将后面切片元素,拷贝到前面切面里面
    //copy()是从前往后添加并覆盖
    copy(s2,s1)
    fmt.Println(s2)   //[8 9 2 3 4]
    fmt.Println(data)  // [8 9 2 3 4 5 6 7 8 9]
}

 

 

     go语言切片实际上是view操作

 

package main

import (
    "fmt"
)

func main() {
    //1go语言切片是对原数组的映射,并没有创建一个真正的切片
    //定义数组
    arr :=[...]int{1,2,3,4,5,6,7}
    //去切片
    s1 :=arr[2:]
    //修改值
    s1[0] = 100
    fmt.Println(s1)   //[100 4 5 6 7]
    fmt.Println(arr)    //[1 2 100 4 5 6 7]
    fmt.Println()
    //go 语言切片美誉取到的位置,可以反向延申,不可向前延申
    s3 :=arr[2:6]
    fmt.Println(s3)  //[100 4 5 6]
    s4 :=s3[3:5]   
    fmt.Println(s4)  //[6 7]
    //容量大小
    fmt.Println("s3=%v,len(s3)=%d,cap(s3)=%d\n",s3,len(s3),cap(s3))
                                            // [100 4 5 6]    4    5
}

 

  4)字符串切片的相互转换

package main
import "fmt"
func main(){
    str := "hello,世界"   //通过字符串字面量初始化 个字符串 str
    a  :=  []byte(str)   //将字符串转换为[]byte 类型切片
    b  :=  []rune(str)  //将字符串转换为[]rune 类型切片
    fmt.Println(a)     //[104 101 108 108 111 44 228 184 150 231 149 140]
    fmt.Println(b)     //[104 101 108 108 111 44 19990 30028]
}

五: map

概述:
go语言内置的字典类型叫map。map的类型格式:
map[K]T,其中K可以是任意可以进行比较的类型
T值类型。map也是一种引用类型

  1)map的创建

package main

import "fmt"

func main() {
    //1 创建map
    var m1 map[int]string
    fmt.Println(m1==nil)
    //赋值报错因为是空的
    //m1[1]="xxx"
    //2 :=
    m2 :=map[int]string{}
    m3 :=make(map[int]string)
    fmt.Println(m2,m3)
    fmt.Println(m2[1])
    //3 指定容量
    m4 :=make(map[int]string,10)
    fmt.Println(m4)
    fmt.Println(m4[1])
}

示例

package main

import "fmt"

func main(){
        ma := map[string]int { "a": 1 , "b": 2}
        fmt.Println(ma [" 
                       
                    
                    

鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
Go语言学习(十)Go 语言结构体发布时间:2022-07-10
下一篇:
Go语言基础(一)发布时间:2022-07-10
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap