Go语法与切片

文章介绍了Go语言中的数学函数,如Ceil、Floor、Round等,以及如何从控制台读取输入。接着讲解了切片和数组的概念,包括长度、容量、地址排列及赋值方式。还讨论了值复制和切片的使用,特别是make函数在定义切片时的作用,以及如何通过切片处理长度和容量的变化。
摘要由CSDN通过智能技术生成
package main

import "fmt"

func main() {
	a := 0x20      //16进制
	fmt.Println(a) //32
	b := 0b100000  //二进制
	fmt.Println(b) //32
	var c = 32     //默认10进制
	fmt.Println(c) //32
	d := a + b + c
	fmt.Printf("%T %d", d, d) //格式化输出%T打印的是类型:int 96
	var e int64 = 100         //var e int64=int64(100)
	fmt.Println(e)//int 32占4个字节,int 64占8个字节

}

一、math方法

math的方法
        方法用途备注
math.Ceil()向上取整
math.Floor()向下取整
math.Round()四舍五入
math.Abs(-2.7)绝对值结果:2.7
math.E  math.Pi常量 
math.MaxInt16 math.MinInt16 极值Int16最大的数,Int16最小数
math.Log10(100)  math.Log2(8)对数结果:2 ,3
math.Max(1,3)   math.Min(-2,3)最大值  最小值
math.Pow(2,3) math.Pow10(3)2^{3}10^{3}
math.Mod(5,2)取模5%2
math.Sqrt(9)开方结果:3

 二、输入

var a1, a2 string
	n, err := fmt.Scan(&a1, &a2) //从控制台输入两个值
	if err != nil {              //err不为空
		panic(err) //程序终止,不会向下执行
	}
	fmt.Println(n)
	fmt.Printf("%T %[1]s,%T %[2]s", a1, a2)


"""
以下是控制台操作结果:
PS E:\projects> go run ./pro1/mian.go
aaa bbb
2
string aaa,string bbb
"""

三、切片与数组

1、切片

var a4=[...]int{1,3,5}//推断有几个元素
fmt.Println(len(a4),cap(a4),a4)

var a5=[5]int{1,5}//给前两个索引赋值
fmt.Println(a5)

var a6=[5]int{1:10,3:50}//定向赋值index:value index值不能超出索引范围
fmt.Println(a6)

a7:=[2][3]int{}//定义一个2行3列的数组
a7:=[2][3]int{1:{100,200,300}}
a7:=[...][3]int{4:{100,2:200,1:300}}//3不能用...代替,这是一个5行的数组

//数组的长度不可变,因此数组的len和cap一致

//go语言不支持负索引

for i,v:=range a6{
    fmt.Println(i,v)
}


2、int数组地址排列 

var a0 = [5]int{1, 3, 5, 7}
	for i := 0; i < len(a0); i++ {
		fmt.Printf("%p\t %d %d %p\n", &a0, i, a0[i], &a0[i])#int 8Bytes
	}
a0[0] = 1000
	fmt.Printf("%p\t %d %d %p\n", &a0, 0, a0[0], &a0[0])

"""
执行结果:
0xc000144030     0 1 0xc000144030
0xc000144030     1 3 0xc000144038
0xc000144030     2 5 0xc000144040
0xc000144030     3 7 0xc000144048
0xc000144030     4 0 0xc000144050
0xc0000103f0	 0 1000 0xc0000103f0
"""

Int数组 

  • 数组必须在编译时就确定大小,之后不能改变
  • 数组首地址就是数组地址
  • 所有元素一个接一个顺序存储在内存中
  • 元素的值可以改变,但是元素地址不变

3、string数组地址排列

var a1 = [...]string{"aab", "ccd", "a", "aaaaaabbbiiiuuuaaaxyz"}
	for i := 0; i < len(a1); i++ {
		fmt.Printf("%p\t %d %s %p\n", &a1, i, a1[i], &a1[i])
	}

"""
执行结果:
0xc000028080	 0 aab 0xc000028080
0xc000028080	 1 ccd 0xc000028090
0xc000028080	 2 a 0xc0000280a0
0xc000028080	 3 aaaaaabbbiiiuuuaaaxyz 0xc0000280b0
"""

数组的地址存储在一个连续的内存中,地址指针指向堆中随意的地址。因此超出也不会影响数组的值

4、值赋值

func typ(arr [5]int) {
	fmt.Printf("%p %d\n", &arr, arr)
}
func main() {
	var a0 = [5]int{1, 3, 5, 7}
	
	fmt.Printf("%p %d\n", &a0, a0)
	var a1 = a0
	fmt.Printf("%p %d\n", &a1, a1)
	typ(a0)
}
"""
执行结果:
0xc0000103f0 [1 3 5 7 0]
0xc000010450 [1 3 5 7 0]
0xc0000104b0 [1 3 5 7 0]
地址不一致,说明这种赋值方式是重新创造了两个副本,属于值复制。
"""

5、make切片

切片:长度可变,容量可变

var a0 = [5]int{1, 3, 5, 7}
	var a1 []int
	fmt.Println(a0, len(a0), cap(a0))
	fmt.Println(a1, len(a1), cap(a1))
	var a2 = make([]int, 0, 0)#第一个参数是切片,第二个参数是长度,第三个参数是当前切片的容量
	fmt.Println(a2, len(a2), cap(a2))

"""
执行结果:
[1 3 5 7 0] 5 5
[] 0 0
[] 0 0
"""

 定义切片建议使用make,可以定义初始容量,减少频繁扩容

 header标量值

  1. 指针:底层数组
  2. len:当前切片的元素个数
  3. cap:当前切片的容量

以下是切片的内存存储:

 由于go中都是值复制的形式对变量进行赋值的,会导致数据垃圾比较多,为了解决扩容等问题因此引入切片。切片是长度可变,容量可变的。

var s0=s1这种方式对于切片来说只是复制了header标量值,因此解决了数组复制副本的问题。

s0 := make([]int, 3, 5)

	s1 := append(s0, 7, 10)
	fmt.Printf("%p\t %p %d\n", &s0, &s0[0], s0)
	fmt.Printf("%p\t %p %d\n", &s1, &s1[0], s1)

"""
执行结果:
0xc000008078	 0xc0000103f0 [0 0 0]
0xc000008090	 0xc0000103f0 [0 0 0 7 10]
"""

如果长度超出数组的容量,则自动扩容。令开辟新的空间去创建一个数组,基址会改变。以上属于未超出容器长度,因此基址不变,只是复制了header而已。

go语言中全都是值传递,整型、数组这样类型的值是完全复制,slice、map、channel、interface、function这样的引用类型也是值拷贝,拷贝的是 标头值。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值