Golang基本类型使用总结 Golang基础(未完待续)

bool

true false

int uint

int8 uint8 (byte)

func main() {
	var x byte
	x = '1'
	fmt.Println(x)
}

int16 uint16

int32 (rune) uint32

func main() {
	var y rune
	y = '我'
	fmt.Println(y)
}

int64 uint64

float32 / float64

complex64 / complex128 TODO

uintptr TODO

array

func main() {
	array := [5]int{1, 2, 3}
	var array2 [5]int
	array2 = *new([5]int)
	array2 = [5]int{1, 2, 3}
	fmt.Println(array)
	fmt.Println(array2)
}
// [number]Type{} 类型为[number]Type,即同一类型不同长度数组是不同类型

struct

type

type的原始类型和之后的类型可以互相赋值,但结构体必须精确一致(成员变量名字、类型和顺序)。

同一原始类型的不同之后的类型不能互相赋值。

func main() {
   var a struct{ x int }
   type Node struct{ x int }
   a = Node{1}
   fmt.Println(a)
   type Node2 struct{ x, y float64 }
   type Node3 struct{ x, y float64 }
   var b Node2
   b = struct{ x, y float64 }{y: 1.1}
   fmt.Println(b)
   //b = struct{ y, x float64 }{y: 1.1}
   /*b = struct {
      y float64
      x float64
   }{y: 1.1}*/
   b = struct {
      x float64
      y float64
   }{y: 1.2}
   fmt.Println(b)
   fmt.Printf("%T\n", b)
   //b = Node3{}	
   type Int int
   var x Int
   x = 1
   fmt.Println(x)
}
D:\gopath\src\mygo>go run main.go
{1}
{0 1.1}
{0 1.2}
main.Node2
1
成员函数

成员函数不区分原始型和指针型,不能重复定义。

type Node struct {
	a int
}

func (node *Node) Output() string {
	return "{!a:" + strconv.Itoa(node.a) + "}"
}
func (node Node) Output2() string {
	return "2{!a:" + strconv.Itoa(node.a) + "}"
}
func main() {
	var node1 = Node{1}
	var node2 = Node{2}
	fmt.Println(node1.Output())
	fmt.Println(node1.Output2())
	fmt.Println(node2.Output())
	fmt.Println(node2.Output2())
}
{!a:1}
2{!a:1}
{!a:2}
2{!a:2}
修改成员变量的成员函数

必须定义为func (*Type)…

type Node struct {
	a int
}

func (node *Node) Set(x int)  {
	node.a = x
}
func (node Node) Set2(x int)  {
	node.a = x
}
func main() {
	var node = Node{1}
	node.Set(3)
	fmt.Println(node)
	node.Set2(4)
	fmt.Println(node)
	(&node).Set(5)
	fmt.Println(node)
	(&node).Set2(6)
	fmt.Println(node)
}
{3}
{3}
{5}
{5}
覆盖

通过type定义新类型重新实现成员函数,进行覆盖。成员函数只适用于本身的类型

type Node struct {
	a int
}
type Node2 Node

func (node Node) Output() string {
	return fmt.Sprint(node)
}
func (node Node) Output2() string {
	return fmt.Sprint(node)
}
func (node2 Node2) Output() string {
	return fmt.Sprint("2", node2)
}
func (node2 Node2) Output3() string {
	return fmt.Sprint("2", node2)
}
func main() {
	node := Node{1}
	node2 := Node2{1}
	fmt.Println(node.Output())
	fmt.Println(node2.Output())
	fmt.Println((Node(node2)).Output())
	fmt.Println("------")
	fmt.Println(node.Output2())
	//fmt.Println(node2.Output2())
	fmt.Println((Node(node2)).Output2())
	fmt.Println("------")
	fmt.Println((Node2(node)).Output3())
	fmt.Println(node2.Output3())
	//fmt.Println((Node(node2)).Output3())
}
D:\gopath\src\mygo>go run main.go
{1}
2{1}
{1}
------
{1}
{1}
------
2{1}
2{1}
输出

对于fmt的Println或Printf("%v %+v"),可以通过func(Type)String() string定义,调用精确匹配的此接口

type Node struct {
	a int
}

func (node *Node) String() string {
	return "{!a:" + strconv.Itoa(node.a) + "}"
}
func main() {
	var node = Node{1}
	fmt.Println(node)
	fmt.Printf("%T\n", node)
	fmt.Printf("%v\n", node)
	fmt.Printf("%+v\n", node)
	fmt.Printf("%#v\n", node)
	fmt.Printf("------")
	fmt.Println(&node)
	fmt.Printf("%T\n", &node)
	fmt.Printf("%v\n", &node)
	fmt.Printf("%+v\n", &node)
	fmt.Printf("%#v\n", &node)
}
D:\gopath\src\mygo>go run main.go
{1}
main.Node
{1}
{a:1}
main.Node{a:1}
------{!a:1}
*main.Node
{!a:1}
{!a:1}
&main.Node{a:1}

string

正确统计中文字数
func main() {
	var s string
	s = "abc啊"
	fmt.Println(len(s))
	fmt.Println(len([]byte(s)))
	fmt.Println(len([]rune(s)))
	fmt.Printf("%T\n", s[0])
	fmt.Printf("%T\n", []byte(s)[0])
	fmt.Printf("%T\n", []rune(s)[0])
}
D:\gopath\src\mygo>go run main.go
6
6
4
uint8
uint8
int32
字符串连接效率

字符串反复+和[]byte append追加效率对比

func main() {
	seed := time.Now().Unix()
	rand.Seed(seed)
	var begin time.Time
	const number = 100000
	var s string
	begin = time.Now()
	for i := 0; i < number; i++ {
		s += strconv.Itoa(rand.Intn(i + 1))
	}
	fmt.Println(len(s))
	fmt.Println(time.Now().Sub(begin).Milliseconds())

	rand.Seed(seed)
	var b []byte
	begin = time.Now()
	for i := 0; i < number; i++ {
		b = append(b, strconv.Itoa(rand.Intn(i+1))...)
	}
	fmt.Println(len(b))
	fmt.Println(time.Now().Sub(begin).Milliseconds())
}
D:\gopath\src\mygo>go run main.go
460740
3886
460740
8
字符串数字互相转换
func main() {
	fmt.Println(fmt.Sprintf("%d", 1234567890))
	fmt.Println(strconv.Itoa(1234567890))
	a, err := strconv.Atoi("1234567890")
	if err != nil {
		panic(err)
	}
	fmt.Println(a)
	a, err = strconv.Atoi("123456.7890")
	if err != nil {
		fmt.Println(err.Error())
		return
	}
	fmt.Println(a)
}
D:\gopath\src\mygo>go run main.go
1234567890
1234567890
1234567890
strconv.Atoi: parsing "123456.7890": invalid syntax

slice []Type

切片构造、初始化、截取、追加、删除
func output(name string, slice []int) {
	fmt.Printf("%s %v\tlen:%v\tcap:%v\t%p\n",
		name, slice, len(slice), cap(slice), &slice[0])
}

func main() {
	s := []int{1, 2, 3, 4, 5}
	output("s", s)

	a := make([]int, 3, 5)
	a = s[1:4]
	output("a", a)

	// 修改派生切片影响基础切片/数组
	fmt.Println("modify slice")
	a = append(a, 6)
	output("a", a)
	output("s", s)
	// 基础数组无法容纳将重新分配空间
	/*a = append(a, 7)
	output("a", a)
	output("s", s)*/

	// 修改基础数组/切片影响派生切片
	fmt.Println("modify base array/slice")
	s = append(s[:2], s[3:]...)
	output("a", a)
	output("s", s)
	// 基础数组无法容纳将重新分配空间
	s = append(s, 7, 8)
	output("a", a)
	output("s", s)
}
D:\gopath\src\mygo>go run main.go
s [1 2 3 4 5]   len:5   cap:5   0xc0000143c0
a [2 3 4]       len:3   cap:4   0xc0000143c8
modify slice
a [2 3 4 6]     len:4   cap:4   0xc0000143c8
s [1 2 3 4 6]   len:5   cap:5   0xc0000143c0
modify base array/slice
a [2 4 6 6]     len:4   cap:4   0xc0000143c8
s [1 2 4 6]     len:4   cap:5   0xc0000143c0
a [2 4 6 6]     len:4   cap:4   0xc0000143c8
s [1 2 4 6 7 8] len:6   cap:10  0xc000010550

map

map设置,获取,删除,遍历
func main() {
	mp := make(map[int]int)
    // set 设置键值
	mp[1] = 1
	mp[2] = 4
	mp[3] = 9
    // 遍历
	for k := range mp {
		fmt.Println(k, "=>", mp[k])
	}
    // 确保键不存在
	delete(mp, 0)
	delete(mp, 1)
    // 获取键
	v, ok := mp[1]
	fmt.Println("v", v, "ok", ok)
	v, ok = mp[2]
	fmt.Println("v", v, "ok", ok)
    // 遍历
	for k, v := range mp {
		fmt.Println(k, "=>", v)
	}
    // 直接输出
	fmt.Println(mp)
	fmt.Printf("%#v\n", mp)
}
D:\gopath\src\mygo>go run main.go
1 => 1
2 => 4
3 => 9
v 0 ok false
v 4 ok true
2 => 4
3 => 9
map[2:4 3:9]
map[int]int{2:4, 3:9}

chan

channel写入只写,读取只读,关闭只写,关闭后读取
func main() {
	go func() {
		i := 1
		for {
			time.Sleep(time.Millisecond * 300)
			fmt.Println("clock:", i)
			i++
		}
	}()
	var ch = make(chan int)
	go func(chin chan<- int) {
		// 无法输入时阻塞
		chin <- 1
		fmt.Println("input sleep")
		time.Sleep(time.Second)
		chin <- 2
	}(ch)
	go func(chout <-chan int) {
		fmt.Println("output sleep")
		time.Sleep(time.Second)
		fmt.Println("ch[1]", <-chout)
		// 无法获取时阻塞,获取成功返回(value, true)
		v, ok := <-chout
		fmt.Println("ch[2]", v, ok)
	}(ch)

	time.Sleep(time.Second * 3)

	var chin chan<- int = ch
	close(chin)
	// 关闭后返回(0, false)
	x, ok := <-ch
	fmt.Println(x, ok)
}
D:\gopath\src\mygo>go run main.go
output sleep
clock: 1
clock: 2
clock: 3
ch[1] 1
input sleep
clock: 4
clock: 5
clock: 6
ch[2] 2 true
clock: 7
clock: 8
clock: 9
0 false

interface TODO

整数字面值为int类型(实际上取值范围是int64),小数字面值为float64类型。

func

可变长度参数
// 这个函数可以传入任意数量的整型参数
func sum(nums ...int) {
	fmt.Print(nums, " ")
	total := 0
	for _, num := range nums {
		total += num
	}
	fmt.Println(total)
}

func main() {
	// 支持可变长参数的函数
	sum(1)
	sum(1, 2, 3)
	// 把切片打散传入
	nums := []int{1, 2, 3, 4}
	sum(nums...)
}
D:\gopath\src\mygo>go run main.go
[1] 1
[1 2 3] 6
[1 2 3 4] 10
函数对象,函数柯里化,参数函数
type IntSlice []int

func (base IntSlice) Map(f func(x int) int) (slice IntSlice) {
	slice = make(IntSlice, len(base))
	for i, v := range base {
		slice[i] = f(v)
	}
	return
}

func main() {
	// 函数对象
	pow := func(x, y int) (ans int) {
		ans = 1
		for y > 0 {
			y--
			ans *= x
		}
		return
	}
	// 函数柯里化
	powBaseX := func(x int) func(y int) int {
		return func(y int) int {
			return pow(x, y)
		}
	}
	// 作为参数的函数
	fmt.Println(IntSlice([]int{1, 2, 3}).Map(powBaseX(2)))
}
D:\gopath\src\mygo>go run main.go
[2 4 8]
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值