package main
import{
"fmt"
}
//声明全局变量 方法一二三是可以的,方法四不行
var gA int =100
func main(){
//方法一 声明一个变量 默认是0
var a int
//方法二 初始化
var b int =100
//方法三
var c=100
//方法四
d:=100
//打印类型%T
fmt.Printf("%T",d)
//声明多个变量
var xx,yy int =100,200
var kk,ll =100,"abc"
var(
vv int =10
jj bool =true
)
}
Go复制代码
package main
import "fmt"
func main(){
// := 自动推导
name := "zhangsan"
var age int
age=18
//%T表示打印类型
fmt.Println("%T",name)
//%p 表示打印地址
fmt.Println("age:%d,内存地址:%p",age,&age)
age=20
//地址不会变
}
变量交换
Go复制代码
package main
func main(){
var a int=100
var b int =200
//交换a,b的值
b,a=a,b
}
var a int=90
switch a{
case 90:
fmt.Println("A")
case 80:
fmt.Println("B")
case 50,60,70:
fmt.Println("C")
default:
fmt.Println("D")
}
switch默认匹配成功后不会执行其他case,如果需要执行其他case,可以使用fallthrough穿透case,break结束穿透
package main
import "fmt"
func swap (pa *int,pb *int){
var temp int
temp=*pa
*pa=*pb
*pb=temp
}
func main(){
var a int=20
var p * int
p=&a
fmt.Println(&a)
fmt.Println(p)
var pp **int //二级指针
pp=&p
fmt.Println(&p)
fmt.Println(pp)
}
package main
//type声明一种新的数据类型myint,是int的一个别名
type myint int
//定义一个结构体,把多种基本类型组合到一起
type Book struct{
title string
auth string
}
func printBook1(book Book){
//值传递 传递一个副本
}
func printBook2(book *Book){
//引用传递
book.auth="678"
}
func main(){
var a myint=10
var book1 Book
book1.title="123"
book1.auth="456"
fmt.Printf("%v",book1)
printBook2(&book1)
}
Go复制代码
package main
type Hero struct{
Name string
age int
}
func (this Hero) Show{
fmt.Println("name=",this.name)
fmt.Println("age=",this.age)
}
func main(){
hero:=Hero{Name:"zhangsan",age:19}
hero.show()
}
Go复制代码
package main
//类名首字母大写,表示其他包也能访问
type Hero struct{
//类的属性首字母大写,表示该属性是对外能够访问的
Name string
age int
}
//方法名大写,其他包也能访问
func (this *Hero) Show{
fmt.Println("name=",this.name)
fmt.Println("age=",this.age)
}
func(this *Hero)GetName()string{
return this.Name
}
func(this *Hero)SetName(name string){
this.name=name
}
func main(){
hero:=Hero{Name:"zhangsan",age:19}
hero.setName("lisi")
hero.show()
}
18、面向对象--继承
Go复制代码
package main
type Human struct{
name string
sex string
}
func (this *Human)Eat(){
fmt.Println("Eat")
}
func (this *Human)Walk(){
fmt.Println("Walk")
}
//继承
type SuperMan struct{
Human //SuperMan类继承了Human类的方法
level int
}
//重写父类方法
func (this *SuperMan)Eat(){
fmt.Println("SuperMan:Eat")
}
//子类新方法
func (this *SuperMan)Fly(){
fmt.Println("Fly")
}
func main(){
h:=Human{"zhangsan","female"}
h.Eat()
//写法1
s:=SuperMan{
Human{
"lisi",
"male"
},
88
}
s.Eat()
//写法2
var sm SuperMan
sm.name="wangwu"
sm.level=99
}
父类的类名写到子类的结构中
19、面向对象--多态
Go复制代码
package main
//interface本质是一个指针,指向当前interface所指向的具体类型
type Animal interface{
Sleep()
GetColor() string //获取动物颜色
GetType() string //获取动物种类
}
//具体的类
type Cat struct{
color string
}
func (this *Cat)Sleep(){
}
func (this *Cat)GetColor() string{
return this.color
}
func (this *Cat)GetType() string{
return "Cat"
}
func main(){
var animal Animal//接口的数据类型,父类指针
animal=&Cat{"Green"}
animal.Sleep()
}
基本的要素:
有一个父类(接口)
有子类,实现了父类的全部接口方法
父类的指针指向子类
20、interface
interface 通用万能类型
Go复制代码
package main
func myFunc(arg interface{}){
fmt.Println(arg)
//interface{} 如何区分此时引用的底层数据类型是什么
//给interface{} 提供"断言"的机制
//判断是否是string
value,ok:=arg.(string)
}
type Book struct{
auth string
}
func main(){
book:=Book{"Go"}
myFunc(book)
}
21、断言
Go复制代码
package main
func main(){
var a string
//a中pair <static type :string,value:"abc">
a="abc"
//allTpe中pair <type:,value:>
var allType interface{}
//allTpe中pair <type:string,value:"abc">
allType=a
//allTpye此时可以断言成string
str,ok:=allTpye.(string)
}
func demo1() error{
//tty: pair<type:*os.File,value:"/dev/path"文件描述符>
tty,err:=os.OpenFile("/dev/path",os.0_RDWR,0)
if err!=nil{
return err
}
//r: pair<type:,value:>
var r io.Reader
//r: pair<type:*os.File,value:"/dev/path"文件描述符>
r=tty
//w: pair<type:,value:>
var w io.Writer
//w:pair<type:*os.File,value:"/dev/path"文件描述符>
w=r.(io.Writer)
}
type Reader interface{
ReadBook()
}
type Writer interface{
WriteBook()
}
type Book struct{
}
func (this *Book) ReadBook(){
}
func (this *Book) WriteBook(){
}
func demo2(){
// b:pair<type:Book,value:Book{}地址>
b:=&Book{}
var r Reader
// r:pair<type:Book,value:Book{}地址>
r=b
r.ReadBook()
var w Writer
//r能断言为(Writer),因为w r具体的type是一致的,Book实现了这两个接口
w=r.(Writer)
w.WriteBook()
}
变量的内部构造有两部分(合起来称为pair):type与value。type(类型)分为static type(静态类型)与concrete type(具体类型)。static type 例如int,string等。concrete type指interface所指向的具体数据类型
22、反射
func ValueOf (i interface{}) Value{...} 0
func TypeOf(i interface{}) Type{...} nil
Go复制代码
package main
import(
"reflect"
)
func reflectNum(arg interface{}){
fmt.Println("type:",reflect.TypeOf(arg))
fmt.Println("value:",reflect.ValueOf(arg))
}
func main(){
var num float64=31415
reflectNum(num)
}
Go复制代码
package main
type User struct{
Id int
Name string
}
func (this User) Call(){
}
func main(){
user:=User{1,"abc"}
}
func Do(input interface{}){
//获取input的type
inputType:=reflect.TypeOf(input)
fmt.Println(inputType.Name())
//获取value
inputValue:=reflect.ValueOf(input)
fmt.Println(inputValue)
//通过type获取里面的字段
/*
1、获取interface的reflect.Type ,通过Type得到NumField,进行遍历
2、得到每个field,数据类型
3、通过filed有一个Interface()方法得到对应value
*/
for i:=0;i<inputType.NumField();i++{
field:=inputType.Field(i)
value:=inputType.Field(i).Interface()
fmt.Printf("%s %v=%v\n",field.Name,field.Type,value)
//Id int 1
}
//通过type调用里面方法
for i:=0;i<inputType.NumMethod();i++{
m:=inputType.Method(i)
//m.Name Call m.Type func(main.User)
}
}
23、结构体标签
Go复制代码
package main
type resume struct{
Name string `info:"name" doc:"myName"`
Sex string `info:"sex"`
}
func findTag(str interface{}){
t:=reflect.TypeOf(str).Elem()
for i:=0;i<t.NumField();i++{
tagString :=t.Field(i).Tag.Get("info")
fmt.Println(tagString)
}
}
func main(){
var re resume
findTag(&re)
}
Go复制代码
package main
import(
"encoding/json"
)
type Movie struct{
Title string `json:"title"`
Year int `json:"year"`
Actors []string `json:"actors"`
}
func main(){
movie:=Movie{"戏剧",2002,[]string{"李","刘"}}
//编码的过程 结构体---->json
jsonStr,err:=json.Marshal(movie)
//解码 json---->结构体
myMovie:=Movie{}
err = json.Unmarshal(jsonStr,&myMovie)
}
四、goroutine与channel
1、goroutine
单进程操作系统的问题:
单一执行流程、计算机只能一个任务一个任务处理
进程阻塞所带来的cpu浪费时间
多进程带来的问题
多进程/线程解决了单进程/线程的阻塞问题,但是
进程/线程数量越多,切换成本越大
多进程伴随着同步竞争(锁、竞争资源冲突等)
调度器的设计策略
复用线程
work stealing机制 :如果存在空闲的本地队列,会偷取其他队列的G来执行
hand off机制:如果G1阻塞,会立即唤醒另一个线程,将G1所关联的P迁移到另一个线程来执行,G1阻塞结束,如果还要继续执行会加入其他队列中,不执行会睡眠或销毁M1