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