package main
import"fmt"type VowelsFinder interface{FindVowels()[]rune}type MyString stringfunc(ms MyString)FindVowels()[]rune{var vowels []runefor_,rune:=range ms {ifrune=='a'||rune=='e'||rune=='i'||rune=='o'||rune=='u'{
vowels =append(vowels,rune)}}return vowels
}funcmain(){
name :=MyString("LiangXiaoQing")var v VowelsFinder
v = name
fmt.Printf("vowels are %c", v.FindVowels())}// vowels are [i a i a o i]
2. Practical use of an interface
type SalaryCalculator interface{CalculateSalary()int}type Permanent struct{
empId int
basicapy int
pf int}type Contract struct{
empId int
basicapy int}type Freelancer struct{
empId int
ratePerHour int
totalHours int}func(p Permanent)CalculateSalary()int{return p.basicapy + p.pf
}func(c Contract)CalculateSalary()int{return c.basicapy
}func(f Freelancer)CalculateSalary()int{return f.ratePerHour * f.totalHours
}functotalExpense(s []SalaryCalculator){
expense :=0for_, v :=range s {
expense = expense + v.CalculateSalary()// 循环添加每个值}
fmt.Printf("Total Expense Per Month $%d", expense)}funcmain(){
p1 := Permanent{
empId:1,
basicapy:4999,
pf:10,}
p2 := Permanent{
empId:2,
basicapy:5999,
pf:20,}
c1 := Contract{
empId:3,
basicapy:3000,}
f1 := Freelancer{
empId:4,
ratePerHour:77,
totalHours:666,}
f2 := Freelancer{
empId:5,
ratePerHour:66,
totalHours:111,}
employees :=[]SalaryCalculator{p1, p2, c1, f1, f2}
fmt.Println(employees)totalExpense(employees)}// [{1 4999 10} {2 5999 20} {3 3000} {4 77 666} {5 66 111}]// Total Expense Per Month $72636
3. Nterface internal representation
type Worker interface{Work()}type Person struct{
name string}func(p Person)Work(){
fmt.Println(p.name,"is Working")}funcdescribe(w Worker){
fmt.Printf("Interface type %T value %v\n", w, w)}funcmain(){
p := Person{
name:"Like",}var w Worker = p
describe(w)
w.Work()}// Interface type main.Person value {Like}// Like is Working
4. Empty interface
funcdescribe(i interface{}){
fmt.Printf("type = %T, value= %v\n", i, i)}funcmain(){
s :="Hello World"describe(s)
i :=55describe(i)
strt :=struct{
name string}{
name:"Like",}describe(strt)}// type = string, value= Hello World// type = int, value= 55// type = struct { name string }, value= {Like}
5. Type assertion
funcassert(i interface{}){
s := i.(int)
fmt.Println(s)//v, s := i.(int)//fmt.Println(v, s) // 56, true 如果是两个值 则是值和true or false}funcmain(){var i interface{}=56assert(i)// 56var s interface{}="Like"assert(s)// panic: interface conversion: interface {} is string, not int}
6. Type switch
funcfindType(i interface{}){switch i.(type){casestring:
fmt.Printf("I am string and my value is %s\n", i.(string))caseint:
fmt.Printf("I am an int and my value is %d\n", i.(int))default:
fmt.Printf("Unknown type\n")}}funcmain(){findType("Like")findType(666)findType(66.99)}// I am string and my value is Like// I am an int and my value is 666// Unknown type
7. Implementing interfaces using pointer receivers VS value receivers
package main
import"fmt"type Describer interface{Describe()}type Person struct{
name string
age int}type Address struct{
state string
country string}func(p Person)Describe(){
fmt.Printf("%s is %d years old\n", p.name, p.age)}func(a *Address)Describe(){
fmt.Printf("State %s Counrty %s", a.state, a.country)}funcmain(){var d1 Describer
p1 := Person{"Like",11}
d1 = p1
d1.Describe()// Like is 11 years old
p2 := Person{"Jack",22}
d1 =&p2 //{Jack 22}
d1.Describe()// Jack is 22 years oldvar d2 Describer
a := Address{"LiangXiaoXiao","China"}
d2 =&a
d2.Describe()// State LiangXiaoXiao Counrty China}// Like is 11 years old// Jack is 22 years old// State LiangXiaoXiao Counrty China`
8. Implementing multiple interfaces
type SalaryCalculators interface{DisplaySalary()}type LeaveCalculator interface{CalculateLeavesLeft()int}type Employee struct{
firstName string
lastName string
basicPay int
pf int
totalLeaves int
leavesTaken int}func(e Employee)DisplaySalary(){
fmt.Printf("%s %s has salary $%d", e.firstName, e.lastName,(e.basicPay + e.pf))}func(e Employee)CalculateLeavesLeft()int{return e.totalLeaves - e.leavesTaken
}funcmain(){
e := Employee{
firstName:"Naveen",
lastName:"Ramanathan",
basicPay:5000,
pf:200,
totalLeaves:30,
leavesTaken:5,}var s SalaryCalculators = e
s.DisplaySalary()var l LeaveCalculator = e
fmt.Println("\nLeaves left =", l.CalculateLeavesLeft())}// Naveen Ramanathan has salary $5200// Leaves left = 25
9. Embedding interfaces
type SalaryCalculators interface{DisplaySalary()}type LeaveCalculator interface{CalculateLeavesLeft()int}type EmployeeOperations interface{
SalaryCalculators
LeaveCalculator
}type Employee struct{
firstName string
lastName string
basicPay int
pf int
totalLeaves int
leavesTaken int}func(e Employee)DisplaySalary(){
fmt.Printf("%s %s has salary $%d", e.firstName, e.lastName,(e.basicPay + e.pf))}func(e Employee)CalculateLeavesLeft()int{return e.totalLeaves - e.leavesTaken
}funcmain(){
e := Employee{
firstName:"Naveen",
lastName:"Ramanathan",
basicPay:5000,
pf:200,
totalLeaves:30,
leavesTaken:5,}var s EmployeeOperations = e
s.DisplaySalary()
fmt.Println("\nLeaves left =", s.CalculateLeavesLeft())}// Naveen Ramanathan has salary $5200// Leaves left = 25
10. Zero value of Interface
package main
import"fmt"type Describer interface{Describe()}funcmain(){var d1 Describer
if d1 ==nil{
fmt.Printf("d1 is nil and has type %T value %v\n", d1, d1)}}// d1 is nil and has type <nil> value <nil>
二、Goroutines
1. How to start a Goroutine?
package main
import("fmt""time")funchello(){
fmt.Println("Hello world goroutine")}funcmain(){gohello()// 没有等待完成就下一步了
time.Sleep(1* time.Second)// 优化添加io操作 则看见了运行hello的输入
fmt.Println("main function")}
2. Starting multiple Goroutines
package main
import("fmt""time")funcnumbers(){for i :=1; i <=5; i++{
time.Sleep(250* time.Millisecond)
fmt.Printf("%d ", i)}}funcalphabets(){for i :='a'; i <='e'; i++{
time.Sleep(400* time.Millisecond)
fmt.Printf("%c ", i)}}funcmain(){gonumbers()goalphabets()
time.Sleep(3000* time.Millisecond)
fmt.Println("main terminated")}// 1a23b4c5deMain Terminated
三、Channels
1. Declaring channels
package main
import"fmt"funcmain(){var a chanintif a ==nil{
fmt.Println("Channel a is nil, going to define it")
a =make(chanint)
fmt.Printf("Type of a is %T", a)}}// Channel a is nil, going to define it// Type of a is chan int
2. Channel example program
package main
import("fmt""time")funchello(done chanbool){
fmt.Println("Hello go routine is going to sleep")
time.Sleep(4* time.Second)
fmt.Println("hello go routine awake and going to write to done")
done <-true// 将 true发送给done通道 表示hello结束运行}funcmain(){
done :=make(chanbool)// 创建done通道 bool类型
fmt.Println("Main going to call hello go goroutine")gohello(done)// 启动goroutine线程并发 不会阻塞主线程 运行hello<-done // done 通道接收数据 阻塞操作 直到接收到数据为止 hello发送了true解除阻塞
time.Sleep(1* time.Second)
fmt.Println("Main received data")}// Main going to call hello go goroutine// Hello go routine is going to sleep// hello go routine awake and going to write to done// Main received data
3. Another example for channels
package main
import("fmt")funccalcSquares(number int, squareop chanint){
sum :=0for number !=0{
digit := number %10
sum += digit * digit
number /=10}
squareop <- sum
}funccalcCubes(number int, cubeop chanint){
sum :=0for number !=0{
digit := number %10
sum += digit * digit * digit
number /=10}
cubeop <- sum
}funcmain(){
number :=589
sqrch :=make(chanint)
cubech :=make(chanint)gocalcSquares(number, sqrch)gocalcCubes(number, cubech)
squares, cubes :=<-sqrch,<-cubech
fmt.Println("Final output", squares + cubes)}// Final output 1536
4. Deadlock
package main
funcmain(){
ch :=make(chanint)
ch <-5}// fatal error: all goroutines are asleep - deadlock!// goroutine 1 [chan send]:// main.main()// D:/one/channel.go:34 +0x31
6. Closing channels and for range loops on channels
funcproducer(chnl chanint){for i :=0; i <10; i++{
chnl <- i
}close(chnl)}funcmain(){
ch :=make(chanint)goproducer(ch)for{
v, ok :=<-ch
fmt.Println(v, ok)if ok ==false{break}
fmt.Println("Received", v, ok)}}// Received 0 true // Received 1 true // Received 2 true // Received 3 true // Received 4 true // Received 5 true // Received 6 true // Received 7 true // Received 8 true // Received 9 true