go基础一


前言

,开始入坑go

首先要有一门语言基础:java,c++等

代码

package main

import (
	"fmt"
	"unsafe"
)

func main()  {
	fmt.Println()

	// 1. 变量和常量
	// var 变量名 类型 [ = 值]
	// 变量名 := 值
	var c int = 4
	a , b := 1 , "hello"
	fmt.Println(a,b,c)
	// Go 语言提供自动内存管理,不需要关心变量的生存期和存放位置,编译器使用栈逃逸技术能够自动为变量分配空间:可能在栈上,也可能在堆上。


	// 2. 常量
	//方式一 类似枚举的iota
	const (
		c0 = iota // c0 == 0
		c1 = iota // c1 == 1
		c2 = iota // c2 == 2
	)
	//方式二 简写模式
	const (
		c3 = 3 // c3 == 3
		c4        // c4 == 3
		c5        // c5 == 3
	)
	//方式三 分开的const语句
	const x = 5 // x == 5
	const y = iota // y == 0
	fmt.Println(c0,x,c3,c4)


	// 3. 数据基本类型
	//布尔类型
	var ok bool
	fmt.Println(ok) //false  不初始化默认false
	ok = true
	fmt.Println(ok) //true

	fals := false
	fmt.Println(fals) //false
	//整型
	var a1 int = 1
	var a2 int32 = 2
	//a2  = a1 //error  不同类型的整形必须进行强制类型转换
	fmt.Println(a2,a1)

	var a3 int = (1 + 2) * 3
	var b3 int = 1000 >> 2
	fmt.Println(a3,b3) //9 250

	//浮点类型
	var b4 float64 = 10.02  // 用于表示包含小数数据,有两种类型分别是float32和float64 浮点数自动类型推倒位float64
	var b5  = 10.03
	fmt.Println(b4,b5) // 10.02 10.03
	//计算机很难对浮点型数精确存储,两个浮点数之间不要用==或!=进行比较,高精度科学计算使用math

	//复数型
	//在计算机中使用两个浮点数表示,一个表示实部,一个表示虚部,complex64是由两个float32构成的,complex128是由两个float64构成的。复数的字面量表示和数学表示法一样。
	var v1 complex64 = 3.1 + 5i
	v2 := 3.1 + 6i
	//Go有三个函数处理复数
	var v = complex(2.1, 3) //构造一个复数
	a6 := real(v1)           //返回复数的实部
	b6 := imag(v2)          //返回复数的虚部
	fmt.Println(a6,b6,v)  //3.1 6 (2.1+3i)

	//字符串
	var a7 = "hello world"
	fmt.Println(a7)
	var a8 = "hello,world"
	b8 := a8[0]
	//a8[1] = 'a' //error  字符串是常量,可以通过类似数组索引访问字节单元,但不能修改某字节的值
	fmt.Println(b8,a8[1])  //104 101

	//字符串转换为切片[]byte(s)时候要慎用,尤其是数据量较大时候,每次转换都需要赋值大量的内容
	b7 := []byte(a7)
	fmt.Println(b7)  //[104 101 108 108 111 32 119 111 114 108 100]
	c7 := a7[1:]    //基于字符串创建的切片和源字符串指向相同的底层字符串数组,一样不能修改,对字符串的切片操作返回的子串仍然是string,而非slice基于字符串创建的切片和源字符串指向相同的底层字符串数组,一样不能修改,对字符串的切片操作返回的子串仍然是string,而非slice
	fmt.Println(c7)  //ello world
	b7_1 := []rune(a7)
	fmt.Println(b7_1)  //字符串和切片的转换:字符串可以转换为字节数组,也可以转换为Unicode的字数组
	//Go内置两种字符类:1.byte的字节类型;2.表示Unicode编码的字符rune。
	//rune在Go内部是int32类型的别名,占用4个字节。
	//Go语言默认字符编码就是UTF-8类型的,如果需要特殊的编码转换,使用Unicode/UTF-8标准包。

	//字符串的运算:拼接、求长度、遍历
	a9 := "hello"
	b9 := "world"
	c9 := a9 + b9	//字符串拼接
	fmt.Println(c9)
	fmt.Println(len(a9))	//len函数获取字符串的长度
	d := "hello,世界"
	//遍历字节数组
	for i := 0; i方法一")
	//方法一:格式化打印  // 'h''e''l''l''o'',''世''界'
	for _, ch1 := range d {
		fmt.Printf("%q",ch1) //单引号围绕的字符字面值,由go语法安全的转义
	}
	fmt.Println("==========>方法二")
	//方法二:转化输出格式  // hello,世界
	for _, ch2 := range d {
		fmt.Print(string(ch2))
	}


	// 指针
	//指针的声明类型为*T, Go同样支持多级指针**T。通过在变量名前面加&来获取变量的地址。
	//在赋值语句中,T出现在“=”左边表示指针声明,T出现在“=”右边表示取指针指向的值(varName为变量名)。
	var a11 =11
	p := &a11
	fmt.Println(p)

	//结构体指针访问结构体字段仍然使用“.”点操作符,Go语言没有“>”操作符。
	type User struct {
		name string
		age  int
	}
	andes := User{
		name: "andes",
		age:  18,
	}
	pp := &andes
	fmt.Println(pp.name) //p.name通过“.”操作符访问成员变量
	//Go不支持指针的运算。Go由于支持垃圾回收,如果支持指针运算,则会给垃圾回收的实现带来很多不便,在C和C++里面指针运算很容易出现问题,因此Go直接在语言层面禁止指针运算。
	//a := 1234
	//p := &a
	//p++ //不允许,报non-numeric type*int错误

	//函数中允许返回局部变量的地址。 Go编译器使用“栈逃逸”机制将这种局部变量的空间分配在堆上。
	//例如 sum()


	//数组
	//	数组的类型名是[n]类型,其中n是数组长度。比如一个包含2个int类型元素的数组类型可表示为[2]int。数组一般在创建时通过字面量初始化,单独声明一个数组类型变量而不进行初始化是没有意义的。
	var arr [2]int                       //声明一个有两个整型的数组,但元素默认值都是0,一般很少这样使用
	array := [...]float64{7.0, 8.5, 9.1} //[...1后面跟字面量初始化列表
	fmt.Println(arr,array)  //[0 0] [7 8.5 9.1]
	//数组的初始化
	arr1 := [3]int{1, 2, 3}   //指定长度和初始化字面量
	arr2 := [...]int{1, 2, 3} //不指定长度,但是由后面的初始化列表数量来确定其长度
	arr3 := [3]int{1: 1, 2: 3}   //指定总长度,并通过索引值进行初始化,没有初始化元素时使用类型默认值
	arr4 := [...]int{1: 1, 2: 3} //不指定总长度,通过索引值进行初始化,数组长度由最后一个索引值确定,没有指定索引的元素被初始化为类型的零值
	fmt.Println(arr1,arr2,arr3,arr4) //[1 2 3] [1 2 3] [0 1 3] [0 1 3]
	//数组的特点
	//(1)数组创建完长度就固定了,不可以再追加元素。
	//(2)数组是值类型的,数组赋值或作为函数参数都是值拷贝。
	//(3)数组长度是数组类型的组成部分,[10]int和[20]int表示不同的类型。
	//(4)可以根据数组创建切片。
	//数组的访问
	array1 := [...]int{1, 2, 3}
	barray := array1[0]
	fmt.Println(barray)
	//数组访问一
	for i,v := range array1 {
		fmt.Println(i,v)
	}
	//数组访问二
	alength := len(array1)
	for i:=0; ib?a:b),这也符合Go的设计哲学,只提供一种方法做事情。
	if分支语句遇到return后直接返回,遇到break则跳过break下方的if语句块。
	 */

	//switch 语句

	//for 语句
	//for 语句对数组、切片、字符串、map、通道的访问
	//访问map
	/**
	for key, value := range map {}
	for key := range map {}

	//访问数组
	for index, value := range array {}
	for index := range array {}
	for _, value := range array {}

	//访问切片
	for index, value := range slice {}
	for index := range slice {}
	for _, value := range slice {}

	//访问通道
	for value := range channel {}

	 */



	// 标签和跳转
	// Go 语言使用标签(Lable)来标识一个语句的位置,用于goto、break、continue 语句的跳转,标签的语法是Lable:Statement
	//goto Lable的语义是跳转到标签名后的语句处执行,goto语句有以下几个特点:
	//goto语句只能在函数内跳转。
	//goto语句不能跳过内部变量声明语句,这些变量在goto语句的标签语句处又是可见的。例如:

	//goto 语句只能跳到同级作用域或者上层作用域内,不能跳到内部作用域内。


	// break
	// continue








}
func sum(a, b int) *int {
	sum := a + b
	return &sum //允许,sum会分配在heap上
}

 参考

https://www.cnblogs.com/WindSun/p/12208321.html

https://blog.csdn.net/linshuhe1/article/details/73331200

Go