目录标题
- 一、Interface
-
- 1. Declaring and implementing an interface
- 2. Practical use of an interface
- 3. Nterface internal representation
- 4. Empty interface
- 5. Type assertion
- 6. Type switch
- 7. Implementing interfaces using pointer receivers VS value receivers
- 8. Implementing multiple interfaces
- 9. Embedding interfaces
- 10. Zero value of Interface
- 二、Goroutines
-
- 1. How to start a Goroutine?
- 2. Starting multiple Goroutines
- 三、Channels
-
- 1. Declaring channels
- 2. Channel example program
- 3. Another example for channels
- 4. Deadlock
- 5. Unidirectional channels
- 6. Closing channels and for range loops on channels
一、Interface
1. Declaring and implementing an interface
package main
import "fmt"
type VowelsFinder interface {
FindVowels() []rune
}
type MyString string
func (ms MyString) FindVowels() []rune {
var vowels []rune
for _, rune := range ms {
if rune == 'a' || rune == 'e' || rune == 'i' || rune == 'o' || rune == 'u' {
vowels = append(vowels, rune)
}
}
return vowels
}
func main() {
name := MyString("LiangXiaoQing")
var v VowelsFinder
v = name
fmt.Printf("vowels are %c", v.FindVowels())
}
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
}
func totalExpense(s []SalaryCalculator) {
expense := 0
for _, v := range s {
expense = expense + v.CalculateSalary()
}
fmt.Printf("Total Expense Per Month $%d", expense)
}
func main() {
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)
}
3. Nterface internal representation
type Worker interface {
Work()
}
type Person struct {
name string
}
func (p Person) Work() {
fmt.Println(p.name, "is Working")
}
func describe(w Worker) {
fmt.Printf("Interface type %T value %v\n", w, w)
}
func main() {
p := Person{
name: "Like",
}
var w Worker = p
describe(w)
w.Work()
}
4. Empty interface
func describe(i interface{}) {
fmt.Printf("type = %T, value= %v\n", i, i)
}
func main() {
s := "Hello World"
describe(s)
i := 55
describe(i)
strt := struct {
name string
}{
name: "Like",
}
describe(strt)
}
5. Type assertion
func assert(i interface{}) {
s := i.(int)
fmt.Println(s)
}
func main() {
var i interface{} = 56
assert(i)
var s interface{} = "Like"
assert(s)
}
6. Type switch
func findType(i interface{}) {
switch i.(type) {
case string:
fmt.Printf("I am string and my value is %s\n", i.(string))
case int:
fmt.Printf("I am an int and my value is %d\n", i.(int))
default:
fmt.Printf("Unknown type\n")
}
}
func main() {
findType("Like")
findType(666)
findType(66.99)
}
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)
}
func main() {
var d1 Describer
p1 := Person{"Like", 11}
d1 = p1
d1.Describe()
p2 := Person{"Jack", 22}
d1 = &p2
d1.Describe()
var d2 Describer
a := Address{"LiangXiaoXiao", "China"}
d2 = &a
d2.Describe()
}
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
}
func main() {
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())
}
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
}
func main() {
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())
}
10. Zero value of Interface
package main
import "fmt"
type Describer interface {
Describe()
}
func main() {
var d1 Describer
if d1 == nil {
fmt.Printf("d1 is nil and has type %T value %v\n", d1, d1)
}
}
二、Goroutines
1. How to start a Goroutine?
package main
import (
"fmt"
"time"
)
func hello() {
fmt.Println("Hello world goroutine")
}
func main() {
go hello()
time.Sleep(1 * time.Second)
fmt.Println("main function")
}
2. Starting multiple Goroutines
package main
import (
"fmt"
"time"
)
func numbers() {
for i := 1; i <= 5; i++ {
time.Sleep(250 * time.Millisecond)
fmt.Printf("%d ", i)
}
}
func alphabets() {
for i := 'a'; i <= 'e'; i++ {
time.Sleep(400 * time.Millisecond)
fmt.Printf("%c ", i)
}
}
func main() {
go numbers()
go alphabets()
time.Sleep(3000 * time.Millisecond)
fmt.Println("main terminated")
}
三、Channels
1. Declaring channels
package main
import "fmt"
func main() {
var a chan int
if a == nil {
fmt.Println("Channel a is nil, going to define it")
a = make(chan int)
fmt.Printf("Type of a is %T", a)
}
}
2. Channel example program
package main
import (
"fmt"
"time"
)
func hello(done chan bool) {
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
}
func main() {
done := make(chan bool)
fmt.Println("Main going to call hello go goroutine")
go hello(done)
<-done
time.Sleep(1 * time.Second)
fmt.Println("Main received data")
}
3. Another example for channels
package main
import (
"fmt"
)
func calcSquares(number int, squareop chan int) {
sum := 0
for number != 0 {
digit := number % 10
sum += digit * digit
number /= 10
}
squareop <- sum
}
func calcCubes(number int, cubeop chan int) {
sum := 0
for number != 0 {
digit := number % 10
sum += digit * digit * digit
number /= 10
}
cubeop <- sum
}
func main() {
number := 589
sqrch := make(chan int)
cubech := make(chan int)
go calcSquares(number, sqrch)
go calcCubes(number, cubech)
squares, cubes := <-sqrch, <-cubech
fmt.Println("Final output", squares + cubes)
}
4. Deadlock
package main
func main() {
ch := make(chan int)
ch <- 5
}
5. Unidirectional channels
func sendData(sendch chan<- int) {
sendch <- 10
}
func main() {
chnl := make(chan int)
go sendData(chnl)
fmt.Println(<-chnl)
}
6. Closing channels and for range loops on channels
func producer(chnl chan int) {
for i := 0; i < 10; i++ {
chnl <- i
}
close(chnl)
}
func main() {
ch := make(chan int)
go producer(ch)
for {
v, ok := <-ch
fmt.Println(v, ok)
if ok == false {
break
}
fmt.Println("Received", v, ok)
}
}