Go_数据类型

字符串, 字符, 字节

字符串: 

go语言中字符串用"双引号"或`反引号`(1左边那个键). 并且反引号还有取消转义的作用

package main

import "fmt"

func main(){
	fmt.Println(`a\na`) // a\na
	fmt.Println("a\na") // a换行a
}

字符串操作

// 字符串拼接
str3 := str1 + str2

// 格式化
package main

import "fmt"

func main(){
	name := "自由"
	age := 18
	var aa string 
	aa = fmt.Sprintf("%s %d",name, age)
	fmt.Println(aa)
}

字符串切片

package main

import "fmt"

func main(){
	str1 := "hello word"
	str2 := str1[2:7]
	fmt.Println(str2)
}

字符串的底层布局: 存放起始内存位置和长度的结构体

package main

import "fmt"

func main(){
	str1 := "hello word"
	str2 := str1[2:7]
	fmt.Printf("%p %p", str1[2], str2[1]) // %!p(uint8=108) %!p(uint8=108)
}

求长度: len(str) 不演示

byte, rune

byte 等同于int8,常用来处理ascii字符

rune 等同于int32,常用来处理unicode或utf-8字符

package main

import (
	"fmt"
)

func main() {

	var str = "hello 你好"

	//golang中string底层是通过byte数组实现的,座椅直接求len 实际是在按字节长度计算  所以一个汉字占3个字节算了3个长度
	fmt.Println("len(str):", len([]byte(str)),[]byte(str)) // len(str): 12 [104 101 108 108 111 32 228 189 160 229 165 189]
	fmt.Println("rune:", len([]rune(str)),[]rune(str) ) //  rune: 8 [104 101 108 108 111 32 20320 22909]
}

string和strconv工具类的使用

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中首次出现的位置,如果没有返回-1
strings.LastIndex(s string, str string) int; 判断str在s中最后出现的位置,如果没有返回-1
strings.Replace(str string, old string, new string, n int); 操作原始字符串替换,n为替换次数
strings.Count(str string, substr string) int; 字符串计数
strings.Repeat(str string, count int) string;  将str重复n次
strings.ToLower(str string) string;    转为小写
strings.ToUpper(str string) string;  转换为大写
strings.TrimSpace(str string) string; 去掉str首尾空白
strings.Trim(str string, cut string) string; 去掉字符串首尾cut字符
strings.TrimLeft(str string, cut string) string; 去掉str左面的cut字符
strings.TrimRight(str string, cut string) string; 去掉str右面的cut字符
strings.Fields(str string) []string ; 返回空格分割的字符串数组
strings.Split(str string, split string) []string ; 返回以split分割str的字符串数组
strings.Join(a []string, sep string) string; 用sep将a中的字符串连接起来

// 类型转换 -- 重点 
strconv.Atoi(s string) (int, error); 将一个字符串转化成数字
strconv.Itoa(i int) string; 将一个数字转化成字符串

数字

int, int8, int16, int32, int64, uint8, uint16, uint32, uint64, float32, float64

类型多多

bool类型

只能存在true和false(默认false)

相关操作符!(非),&&(与),||(或) .短路运算

数组与切片

数组 : 定长的存放相同数据类型的容器, 其中元素的内存是连续的

slice : 切片是数组的一个引用,因此切片是引用类型

但是切片的长度是会改变的, 当向他添加元素超出了他的容量时, 会重新分配内存

使用len(数组/切片)可以获得数组大小和slice中元素个数, cap(切片)可以获得切片的容量大小

数组相关操作

// 声明
// var a [len]type
// 长度是数组类型的一部分. 因此,[5] int和[10]int是不同的类型

// 数组可以通过下标来访问, 赋值

// 数组是值传递, 赋值或传参都会产生副本
package main

import "fmt"

func main() {
	a := [5]int{1,2,3,4,5}
	fmt.Println(a)
	b := a
	fmt.Printf("%p %p",&a, &b) // 0x10c2a0a0 0x10c2a0e0
}

切片相关操作

// slice的初始化: make函数或者数组切片,数组的切片得到的是slice对象
// make()初始化
var a []int // 声明一个int类型的切片, 与数组的区别就是他不用指定长度
a = make([]int, 5) // 分配内存, 设置大小

// make方法
make([]type, len)
make([]type, len, cap)

//数组切片初始化
package main

import "fmt"

func main() {
	var a = [4]int{1,2,3,4}
	b:=a[:]
	fmt.Println(b)
}

// 添加值
package main

import "fmt"

func main() {
	a := make([]int, 5)
	b := append(a, 1)
	fmt.Println(a) // [0 0 0 0 0]
	fmt.Println(b) // [0 0 0 0 0 1]
}

// 分解添加
var a = []int{1,2,3}
var b = []int{4,5,6}
a = append(a, b…)

切片内部

当由数组得到切片时, 其实指向的是同一地址, 修改切片元素时, 列表也会被修改,   当长度变长后重新分配了内存, 再去修改,不会去改变数组

package main

import "fmt"

func main() {
	var a = [4]int{1,2,3,4}
	b:=a[:]
	b[0]=100
	fmt.Println(a) // [100 2 3 4]
	fmt.Println(b) // [100 2 3 4]
	b = append(b,100)
	b[0] = 1
	fmt.Println(a) // [100 2 3 4]
	fmt.Println(b) // [1 2 3 4 100]
}

引用类型

切片属于引用类型(主要是因为其内部结构, 指向的是同一地址)

package main

import "fmt"

func main() {
	a := make([]int,5)
	fmt.Println(a) // [0 0 0 0 0]
	b := a
	fmt.Printf("%p %p\n",&a, &b) // 0x10b5c0c0 0x10b5c0f0 外部地址不同
	a[0] = 1
	fmt.Println(a) // [1 0 0 0 0]
	fmt.Println(b) // [1 0 0 0 0]

}

拷贝, 赋值其内部指向的数组

copy(new_slice1, old_slice2)

排序 -- sort包

package main

import (
    "sort" // 该包
)

func main(){
    // 整数类型排序
    var a = [...]int{1,4,2,5}
    sort.Ints(a[:]) // 需要传递一个切片 
    
    // 字符串排序
    var b = [...]string{"abc", "cba"}
    sort.Strings(b[:])
    
    // 浮点数排序
    var c = [...]float64{1.11, 2.11}
    sort.Float64s(c[:])
    
    // 查找, 返回的是排序后的位置
    index := sort.SearchInts(a[:], 2)
}

指针

指针变量: 值存放的是内存地址, 可以通过该内存地址找到那个位置

指针变量声明

var 标识符 *type

 ps: 通过类型可以判断所占内存长度和在内存中的存储方式, 在存取的那个位置向后移动固定长度便能得到该元素

在比较复杂一点的就是指向指针的指针 : var 标识符 **type

指针操作符

&(非指针变量) 取该变量的地址
*(指针变量) 取该变量的值/也可进行赋值操作,修改指针变量指向地址的值

非引用类型的变量可以通过传递指针的方式完成对原值的修改

package main

import "fmt"

func aa(int2 *int){
	*int2 = 100
}
func main() {
	var a = 10
	aa(&a)
	fmt.Println(a) //100
}

map

 键值存储的数据结构, 类似python的字典,不过要声明键值的类型

声明及初始化

//var map1 map[keytype]valuetype
var a map[int]string
var a map[string]map[string]string // key是string, value是map , 像这种嵌套结构的zhi也是需要make的

// 初始化
var a map[string]string
make(a, 10)
// 或
var a map[string]string = map[string]string{"key":"value"}

// 接上面的那个嵌套结构
package main

import "fmt"

func main() {
	var a map[string]map[string]string
	a = make(map[string]map[string]string,10)
	a["wo"] = make(map[string]string,10)
	fmt.Println(a) // map[wo:map[]]
	a["wo"]["ni"] = "你谁啊"
	fmt.Println(a) // map[wo:map[ni:你谁啊]]
}

map操作

// 赋值
var a map[string]string = map[string]string{“hello”: “world”}
a[“hello”] = “world”

// 取值 ok是bool值,可以通过ok来判断是否有值
Val, ok := a[“hello”]

//遍历
for k, v := range a {
    fmt.Println(k,v)
}

// 删除
delete(a,"hello")
// 长度
len(a)

channel

另说

posted @ 2018-09-08 16:14  瓜田月夜  阅读(101)  评论(0)    收藏  举报