Go语言学习(一):变量常量、基本类型、数组

目录

1、init函数和main函数

2、变量和常量

3、基本类型:

4、数组

1、init函数和main函数

相同点:

两个函数在定义时不能有任何的参数和返回值,且Go程序自动调用。
不同点:
init可以应用于任意包中,且可以重复定义多个。
main函数只能用于main包中,且只能定义一个。

两个函数的执行顺序:
调用顺序:
对同一个go文件的init()调用顺序是从上到下的。
对同一个package中不同文件是按文件名字符串比较“从小到大”顺序调用各文件中的init()函数。
对于不同的package,如果不相互依赖的话,按照main包中"先import的后调用"的顺序调用其包中的init(),如果package存在依赖,则先调用最早被依赖的package中的init(),最后调用main函数。import _ 包路径  只是引用该包,仅仅是为了调用init()函数,所以无法通过包名来调用包中的其他函数
import _ "./hello"

2、变量和常量

var 变量名 变量类型

批量声明用()

var (

    a string

    b int

)

类型推导:var name string = "pprof.cn"

短变量声明:n := 10

_ 匿名变量不占用命名空间,不会分配内存,所以匿名变量之间不存在重复声明。 (在Lua等编程语言里,匿名变量也被叫做哑元变量。)

常量:var 换成 const

iota:是go语言的常量计数器,只能在常量的表达式中使用。 iota在const关键字出现时将被重置为0。const中每新增一行常量声明将使iota计数一次(iota可理解为const语句块中的行索引)。 使用iota能简化定义,在定义枚举时很有用。

package main

import "fmt"


func iota_use1() {
	//会顺延a,b的规则递增
	const (
		a, b = iota + 1, iota + 2 //1,2
		c, d                      //2,3  iota=1,c=1+1,d=1+2
		e, f                      //3,4
	)
	fmt.Printf("a=%d,b=%d,c=%d,d=%d\n", a, b, c, d)
}
func iota_use2() {
	//e会顺延d的规则递增
	const (
		a = iota //0
		b        //1
		_
		d = iota + 1 //3+1
		e            //4+1
	)
	fmt.Printf("a=%d,b=%d,d=%d,e=%d\n", a, b, d, e)
}
func iota_use3() {
	//每当某个枚举被重置(即后面使用iota重新赋值时),则需要从第一个枚举数到当前的次序
	const (
		a = iota //0
		b        //1
		_
		d = iota + 1 //3+1=4
		e            //4+1=5
		f = iota + 2 //5+2=7
		g = iota     //6
	)
	fmt.Printf("a=%d,b=%d,d=%d,e=%d,f=%d,g=%d\n", a, b, d, e, f, g)
}

func main() {
	iota_use1()
	iota_use2()
	iota_use3()
}

3、基本类型:

byte和rune类型

uint8类型,或者叫 byte 型,代表了ASCII码的一个字符。

rune类型,代表一个 UTF-8字符。

字符串底层是一个byte数组,所以可以和[]byte类型相互转换。字符串是不能修改的 字符串是由byte字节组成,所以字符串的长度是byte字节的长度。 rune类型用来表示utf8字符,一个rune字符由一个或多个byte组成。

修改字符串:

要修改字符串,需要先将其转换成[]rune或[]byte,完成后再转换为string。无论哪种转换,都会重新分配内存,并复制字节数组。

 强制类型转换:T(表达式)

4、数组

1. 数组:是同一种数据类型的固定长度的序列。

2. 数组定义:var a [len]int,比如:var a [5]int,数组长度必须是常量,且是类型的组成部分。一旦定义,长度不能变。

3. 长度是数组类型的一部分,因此,var a[5] int和var a[10]int是不同的类型。

4. 数组可以通过下标进行访问,下标是从0开始,最后一个元素下标是:len-1

for i := 0; i < len(a); i++ {}

for index, v := range a {}

5. 访问越界,如果下标在数组合法范围之外,则触发访问越界,会panic

6. 数组是值类型,赋值和传参会复制整个数组,而不是指针。因此改变副本的值,不会改变本身的值。

7.支持 "=="、"!=" 操作符,因为内存总是被初始化过的。

8.指针数组 [n]*T,数组指针 *[n]T。

内置函数 len 和 cap 都返回数组长度 (元素数量)。

package main

import (
	"fmt"
	"math/rand"
	"time"
)

// byte和rune类型

// 遍历字符串
func traversalString() {
	s := "pprof.cn博客"
	for i := 0; i < len(s); i++ { //byte
		fmt.Printf("%v(%c) ", s[i], s[i])
	}
	fmt.Println()
	for _, r := range s { //rune
		fmt.Printf("%v(%c) ", r, r)
	}
	fmt.Println()
}

// 修改字符串
// 要修改字符串,需要先将其转换成[]rune或[]byte,完成后再转换为string。无论哪种转换,都会重新分配内存,并复制字节数组。
// 强制类型转换:T(表达式)
func changeString() {
	s1 := "hello"
	// 强制类型转换
	byteS1 := []byte(s1)
	byteS1[0] = 'H'
	fmt.Println(string(byteS1))

	s2 := "博客"
	runeS2 := []rune(s2)
	runeS2[0] = '狗'
	fmt.Println(string(runeS2))
}

// 112(p) 112(p) 114(r) 111(o) 102(f) 46(.) 99(c) 110(n) 229(å) 141() 154() 229(å) 174(®) 162(¢)
// 112(p) 112(p) 114(r) 111(o) 102(f) 46(.) 99(c) 110(n) 21338(博) 23458(客)
// Hello
// 狗客

// 数组

func array_use() {
	a := [3]int{1, 2}           // 未初始化元素值为 0。
	b := [...]int{1, 2, 3, 4}   // 通过初始化值确定数组长度。
	c := [5]int{2: 100, 4: 200} // 使用引号初始化元素。
	d := [...]struct {
		name string
		age  uint8
	}{
		{"user1", 10}, // 可省略元素类型。
		{"user2", 20}, // 别忘了最后一行的逗号。
	}
	fmt.Println(a, b, c, d)
	//多维
	e := [2][3]int{{1, 2, 3}, {4, 5, 6}}
	f := [...][2]int{{1, 1}, {2, 2}, {3, 3}} // 第 2 纬度不能用 "..."。
	fmt.Println(e, f)
}

//值拷贝行为会造成性能问题,通常会建议使用 slice,或数组指针。
//什么拷贝内存地址都变了???

func test(x [2]int) {
	fmt.Printf("值拷贝 x: %p\n", &x)
	x[1] = 1000
}
func test2(x *[2]int) {
	fmt.Printf("引用拷贝 x: %p\n", &x)
	x[1] = 1000
}
func slice_copy(x []int) {
	x[1] = 1000
	fmt.Printf("slice拷贝 x: %p\n", &x)
}
func array_copy() {

	a := [2]int{}
	fmt.Printf("a: %p\n", &a)

	test(a)
	fmt.Println(a)
	test2(&a)
	fmt.Println(a)

	b := []int{0, 0}
	fmt.Printf("b: %p\n", &b)
	slice_copy(b)
	fmt.Println(b)

}

// 多维数组遍历
func arrays() {

	var f [2][3]int = [...][3]int{{1, 2, 3}, {7, 8, 9}}

	for k1, v1 := range f {
		for k2, v2 := range v1 {
			fmt.Printf("(%d,%d)=%d ", k1, k2, v2)
		}
		fmt.Println()
	}
}

// 练习1:求数组所有元素之和
func sumArr(a [10]int) int {

	sum := 0
	for i := 0; i < len(a); i++ {
		sum += a[i]
	}
	return sum
}

// 练习1:求数组所有元素之和
func learn1() {
	rand.Seed(time.Now().Unix())
	var a [10]int
	for i := 0; i < len(a); i++ {
		// seed()种子默认是1
		//产生一个0-100的随机数,包括100吗?
		a[i] = rand.Intn(100)
	}
	sum := sumArr(a)
	fmt.Println("sum=", sum)
}

// 练习2:
// 找出数组中和为给定值的两个元素的下标,例如数组[1,3,5,8,7],
// 找出两个元素之和等于8的下标分别是(0,4)和(1,2)
func findSum(a []int, x int) {
	for i := 0; i < len(a); i++ {
		for j := i + 1; j < len(a); j++ {
			if a[i]+a[j] == x {
				fmt.Printf("(%d,%d)\n", i, j)
			}
		}
	}
}
func learn2() {
	a := []int{1, 3, 5, 8, 7}
	findSum(a, 8)
}
func main() {
	// traversalString()
	// changeString()
	// array_use()
	//array_copy()
	//arrays()
	learn2()
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值