go 入门学习

package main // package main 入口包,必须有的

// format 标准输入输出格式包
import 	(
	"fmt"
	"math/rand"      //随机数
	"time"
	"errors"
	"os"
	"bufio"
	"io"
	"strings"	//字符串
	"strconv"	//字符串转换
)

func main() {
    fmt.Println("Hello, World!")

	// 定义变量
	var v0 int =100
	fmt.Println(v0)

	// 自动推导类型   变量名:=值
	PI:=3.14
	PI=3.141
	fmt.Println(PI)

	// 多重赋值
	a,b,c,d:=10,20,30,40
	fmt.Println(a,b,c,d)

	// 匿名变量 _ 下划线来代表,用于丢弃数据不处理
	// _,i,_,j :=1,2,3,4

	// 格式输出
	// %d 占位符 整形数据
	// %f 浮点型    %.3f xiaoshudian小数点保留3位
	// %t 布尔类型
	// s% 字符串类型
	// %c 字符(字节byte)类型
	// %p 数据的内存地址(&a)
	// %T 打印变量对应的数据类型
	// %% 打印出百分号%
	// %b 将数据以二进制输出
	// %x %X 输出一个16进制数据
	fmt.Println("字符串 %s","sss")

	//格式输入
	var a1 int       
	var a2 string
	// &取地址运算符
	// fmt.Scan(&a1,&a2)
	// 输入没有空格
	// fmt.Scan("%d%s",&a1,&a2)
	fmt.Println(a1)
	fmt.Println(a2)

	// 识别进制
	aa:=0123    // 八进制数据, 以0开头的是八进制数据
	cc:=0x123   // 十六进制数据
	fmt.Println(aa,cc)

	// 常量  , 储存在数据区,不能通过&来访问
	const a3 int =10
	// 字面常量
	fmt.Println(123)


	// iota枚举
	const 
	(
		ia=iota  //0
		ib=iota	 //1
		ic=iota  //2
		id,ie=iota,iota    //同一行值是相同 

	)
	fmt.Println(ia,ib,ic,id,ie)

	//if
	var score int =900
	if score>600 { //{ 要和if在同一行不然报错
		fmt.Println("score>600")
	}

	switch score {
	case 900:
		fmt.Println("score==900")
		//fallthrough //继续执行下一个case
	case 500:
		fmt.Println("score==500")
	default:
		fmt.Println("not found")
	}

	//for
	for i:=0;i<10;i++ {
		fmt.Println(i)
	}
    // for ; ; {}  //死循环


	plus(3,5,6)


	// 匿名函数
	f:=func (a int, b int) int {
		fmt.Println(a+b)
		return a+b
	}
	f(3,4)

	// 闭包
	ff:=test2()   //获得test2的返回值,返回值是一个函数
	fmt.Println(ff())    // 1
	fmt.Println(ff())    // 2


	// 数组
	var arr [10]int =[10]int{3,6,22}  
	arr2:=[10]int{2,7,9}     
	arr3:=[...]int{2,7,9}     
	arr[0]=3
	arr[2]=5
	fmt.Println(len(arr)) 
	fmt.Println(len(arr3)) 
	//range 遍历集合信息
	for i,v:= range arr2{
		fmt.Println(i,v)
	}

	// 二维数组
	arr4:=[3][4]int{{1,2,3,4},{6,6,7,8},{9,10,11,12}}
	fmt.Println(arr4)
	fmt.Println(arr4[0])   //二维数组的第一行

	// 随机数
	testrand() 

	// 切片   var 切片名 []数据类型      中括号里面不写元素个数 
	// var s[] int    //空切片
	// fmt.Println(s)
	var s2 []int=[]int{44,66,73,4}
	fmt.Println(s2)
	// make([]数据类型,长度)
	s:=make([]int,5)
	s[0]=123
	s=append(s,678)
	s=append(s,67,6,634,80)
	fmt.Println(s)
	//切片截取
	// 切片名[起始下标:]
	//slice:=s[2:]
	// slice:=s[:2]   //切片名[:结束下标]
	// slice:=s[2:5]  
	slice:=s[2:5:6]   //切片名[起始下标:结束下标:容量]
	fmt.Println(slice)
	// copy 切片拷贝 copy(s1,s2)


	// map
	// map[keyType]ValueType
	// var m map[int]string
	m:=make(map[int]string,1)
	m[100]="张三"
	m[120]="李四"
	fmt.Println(m)
	for k,v:=range m {
		fmt.Println(k,v)
	}
	m2:=map[string]int{"王五":10,"赵四":30}
	fmt.Println(m2)
	//v,ok=m[1]   //第一个返回值返回key对应的value,    第二个返回值返回key是否存在
	// 删除
	delete(m2,"王五")
	fmt.Println(m2)


	// 结构体
	type Student struct{
		id int
		name string
		age int
		addr string
	}

	var stu Student
	stu.id=101
	stu.name="s11"
	stu.age=18
	stu.addr="beijing"
	// var stu2 Student=Student{101,"guany",18,"shandong"}   
	// stu2:=Student{id:101,name:"guany",age:18,addr:"shandong"}   
	var stu2 Student=Student{id:101,name:"guany",age:18,addr:"shandong"}   
	fmt.Println(stu2.name)
	//可以用== 和!= 比较结构体


	//指针
	var p * int    //空指针
	var pa int=10
	p=&pa
	*p=34	//修改指针所指向内存地址的内容
	fmt.Println(p)
	fmt.Println(pa)
	// 创建内存空间(在堆区创建) ,只需要创建,并不需要管理空间的释放
	var p1 *int
	p1=new(int)
	fmt.Println(p1)



	// 面向对象
	type person struct{
		name string
		age int
		sex string
	}

	type students struct
	{
		// 通过匿名字段实现继承
		person	//结构体名称作为结构体成员
		id int
		score int
	}


	// 数据类型绑定方法
	testadd() 
	testprintinfo()

	// 方法继承
	testfathermethod()

	//接口
	testinterface()

	// 多态
	testSay() 

	// 空接口  可以接收任意类型的数据
	var inter interface{}
	inter=10
	fmt.Printf("%d\n", inter)
	inter="hello"
	fmt.Printf("%s\n", inter)
	// var i []interface{}   //空接口切片
	// i=append(i,2,"ddd",[3]int{1,2,3})


	// 类型断言
	var vv interface{}=100
	data,ok:=vv.(int)     //需要是接口类型才可以
	if(ok){
		fmt.Printf("整型数据 %d\n", data)
	}


	// 异常处理
	execerror()
	testerror2(10,0)


	// 文件
	dofile()


	// 字符串
	dostring()



}  // main

// 不定参数函数
func plus(arr ...int){
	sum:=0
	for _,data:=range arr{
		sum+=data
	}
	fmt.Println(sum)
}


//闭包 +匿名函数 实现在栈区的本地化(持久化)
//返回类型是 func() int
func test2() func() int {
	var a int 
	return func () int {
		a++
		return a
	}
}

// 随机数测试
func  testrand()  {
	// 添加随机数种子
	rand.Seed(time.Now().UnixNano())
	// 随机数默认是根据时间 1970.1.1.0.0.0 来算的,如果没有添加随机数种子,那么结果都一样
	fmt.Println( rand.Intn(123) ) // 生成0-123的随机数
}


// 指针作为参数
func swap(a *int,b *int){
	temp:=*a
	*a=*b
	*b=temp
}

// ------------------------------------
//为存在的类型绑定方法
//1. 为存在的数据类型起别名
type Int int
//2. 定义函数
// func (方法接收者)方法名(c参数列表)返回值类型
func (a Int)add(b Int)Int{
	return a+b
}
func testadd()  {
	var a Int=5
	b:= a.add(5)
	fmt.Println(b)
}
// ------------------------------------

type Stu struct
{
	name string
	age int
	sex string
}

type Stu2 struct
{
	Stu
	score string
	id int
	 
}

type Stu3 struct
{
	id int	 
}

func (s Stu3)SayHello(){
	fmt.Println("stu33 hello")
}

func (s Stu)PrintInfo() {
	fmt.Println(s.name)
	fmt.Println(s.age)
	fmt.Println(s.sex)
}
//无法改变结构体成员的值
func (s Stu)EditInfo(name string,age int ,sex string) {
	s.name=name
	s.age=age
	s.sex=sex
}
func (s *Stu)EditInfo2(name string,age int ,sex string) {
	s.name=name
	s.age=age
	s.sex=sex
}

func (s Stu)SayHello(){
	fmt.Println("stu hello")
}
// 方法重写
func (s Stu2)SayHello(){
	fmt.Println("stu22 hello")
}


func testprintinfo(){
	fmt.Println("----------testprintinfo:---------------")
	var s Stu=Stu{"liu11",19,"nan"}
	s.EditInfo("liu22",11,"nan")     //无法改变结构体成员的值
	s.PrintInfo()
	(&s).EditInfo2("liu22",11,"nan")
	s.PrintInfo()
}

//测试调用父类的方法
func testfathermethod(){
	fmt.Println("-----------testfathermethod --------------")
	var  stu2 Stu2 =Stu2{Stu{"liu33",19,"nan"},"99",30}
	stu2.name="lisss"
	stu2.PrintInfo()

	stu2.SayHello()    //方法重写,子类的方法调用
	stu2.Stu.SayHello()   //调用父类的方法
}

// 接口
type Humaner interface
{
	SayHello()
}

func testinterface(){
	fmt.Println("------------testinterface: -------------")
	var s Stu=Stu{"liu11",19,"nan"}
	var h Humaner
	h=&s
	h.SayHello()
}

// 多态
func Say(h Humaner){
	h.SayHello()
}

func  testSay()  {
	fmt.Println("------------testSay: -------------")
	var s Stu=Stu{"liu11",19,"nan"}
	var s2 Stu3=Stu3{19}

	Say(&s)
	Say(&s2)
}

// 接口继承
type Personer interface{
	Humaner  //匿名字段,继承SayHello
	sing(lrc string)
}


// ------------------------------------
//异常处理
// 返回两个值
func testerror(a int ,b int)(value int,err error)  {
	//0不能作为除数
	if b==0{
		// panic("不能作为除数")    //调用panic后 程序直接终止了
		err=errors.New("0不能作为除数")
		return
	}
	value=a/b
	return
}

func execerror()  {
	value,err:=testerror(10,0)
	if err!=nil{
		fmt.Println(err)
		return
	}
	fmt.Println(value)
}

// 通过recover和匿名函数进行拦截错误
func testerror2(a int ,b int)int  {
	defer func(){
		// recover 从panic异常中重写获取控制权
		recover()   //返回类型是接口类型
		// err:=recover()  
		// if err!=nil{
			// fmt.Println(err)
		// }
	}()
	value:=a/b
	return value
}




// ------------------------------------
// 文件

func dofile()  {

	// os.Create 文件不存在会创建新文件,存在会覆盖原有内容
	//    fp,err:=os.Create("./test.txt")   // "D:/a.txt"
	// 打开文件  OpenFile(路径,打开模式,打开权限)
	// Open(路径) 只读方式打开
   fp,err:=os.OpenFile("./test.txt",os.O_RDWR,6)    // 

   if(err!=nil){
	   fmt.Println("文件创建或者 打开失败。")
	   return
   }
	//    关闭文件  
	defer fp.Close()      //defer 会在最后调用
	fmt.Println("文件创建成功。")

	//    写入文件  
   fp.WriteString("hello")
   n,err:= fp.WriteString("hello\r\n")   //window文本换行 是\r\n
   fmt.Println("写入的个数",n)
   fmt.Println(err)

	//    写字符串切片
   b:=[]byte{'l','2','y'}
   fp.Write(b) 
   str:="heeey"
   b2:=[]byte(str) //字符串转成字符切片
   fp.Write(b2) 

  //   WriteAt 指定位置写入
	//   第二个参数是相对默认光标位置的偏移量
	b3:=[]byte("哈喽")
   fp.WriteAt(b3,0)

 
	// io.SeekCurrent io.SeekEnd  io.SeekStart
	// File.Seek(offset, whence),设置光标的位置(文件的当前位置)  offset,偏移量   whence,从哪开始:0从头,1当前,2末尾
	//  复数向左偏移 正数向右偏移
   n2,_:=fp.Seek(0,2)  //光标从末尾开始偏移0,光标位置在末尾
   fmt.Println("光标的位置",n2)
   fp.WriteAt(b3,n2)


//    文件读取
   fp.Seek(0,0)
   br:=make([]byte,1024)
   fp.Read(br)
//    fmt.Printf("%s",br)
//    fmt.Println(string(br))

	fp.Seek(0,0)
	//    创建切片缓冲区
	r:= bufio.NewReader(fp)
	for{
		//   读取一行内容
		bn,err:= r.ReadBytes('\n')
		fmt.Println(string(bn))
		if(err==io.EOF){
			break
		}
	}

}

// ------------------------------------
// 字符串
func dostring()  {
	str:="hello"
	// 字符串查找
	value:=strings.Contains(str,"llo")
	fmt.Println(value)
	// 字符串拼接 Join
	s:=[]string{"dd","ssf","4d"}
	str2:=strings.Join(s,"-")
	fmt.Println(str2)

	// 字符串查找位置  Index ,找不到返回-1
	strings.Index(str,"l")

	// 重复字符串, 
	str4:=strings.Repeat("gpp",3)
	fmt.Println(str4)

	// 替换 Replace (字符串,被替换的内容,替换后的内容,替换次数)
	str6:=strings.Replace(str,"ll","ss",1)
	fmt.Println(str6)

	// 分割 Split     返回[]string
	// strings.Split(str,",")

	// Trim 去掉字符串前后指定的内容   strings.Trim(str," ")

	// Fields 去掉字符串的空格,并且按空格分割返回 切片


	// 字符串转换
	// Format系列函数   将其他类型转成字符串
	bs:= strconv.FormatBool(false)
	fmt.Println(bs)
	// strconv.FormatInt(123,10)   //参数  值,进制
	// strconv.FormatFloat(1.23,'f',3,64) 

	// Parse系列函数 把字符串转成其他类型
	
	str8:="true13"
	bs2,err:=strconv.ParseBool(str8)
	if(err!=nil){
		fmt.Println(err)
	}else{
		fmt.Println(bs2)
	}
	// strconv.ParseInt(str,10,64)
	// strconv.Atoi	
	// strconv.ParseFloat	

	// Apppend系列函数 将数据添加到字节数组中
	sl:=make([]byte,0,1024)
	sl=strconv.AppendBool(sl,false)
	sl=strconv.AppendInt(sl,166,10)   //第二个参数为为要追加的数据,第二个是指定10进制
	sl=strconv.AppendQuote(sl,"heeoo") 
	// AppendFloat
	fmt.Println("slice= ",sl)
	fmt.Println(string(sl))

}





// go mod init test3
//  go env -w GO111MODULE=auto

// 执行命令
// go run hello.go 

上一篇:【转】开发者必备,超实用的PHP代码片段!


下一篇:Go并发编程学习总结