zoukankan      html  css  js  c++  java
  • Go语言的学习之旅【六】

    一、接口

    type Car interface { //定义一个Car的接口
    	what() //定义一个方法
    }
    type Bicycle struct {
    }
    type Motor struct {
    }
    
    func (bicycle Bicycle) what() {
    	fmt.Println("I am Bicycle")
    }
    func (bicycle Bicycle) speed() {
    	fmt.Println("I am Bicycle,speed 15km/h")
    }
    func (motor Motor) what() {
    	fmt.Println("I am Motor")
    }
    
    func main() {
    	var car Car
    	car = new(Bicycle)
    	car.what()
    	car = new(Motor)
    	car.what()
    	var bicycle = new(Bicycle) //这个代表一个指针
    	bicycle.speed()
    
    }
    

      

    二、错误异常

    // 定义一个 DivideError 结构
    type DivideError struct {
    	dividee int
    	divider int
    }
    
    // 实现 `error` 接口
    func (de *DivideError) Error() string {
    	strFormat := `
        Cannot proceed, the divider is zero.
        dividee: %d
        divider: 0
    `
    	//fmt.Println("de:",&de)
    	return fmt.Sprintf(strFormat, de.dividee)
    }
    // 定义 `int` 类型除法运算的函数
    func Divide(varDividee int, varDivider int) (result int, errorMsg string) {
    	if varDivider == 0 {
    		dData := DivideError{
    			dividee: varDividee,
    			divider: varDivider,
    		}
    		errorMsg = dData.Error()
    		//fmt.Println("dData:",&dData)
    		return
    	} else {
    		return varDividee / varDivider, ""
    	}
    
    }
    func Sqrt(f float64) (float64, error) {
    	if f < 0 {
    		return 0, errors.New("math: square root of negative number")
    	}
    	return math.Sqrt(f), nil
    }
    func main() {
    	var a, err = Sqrt(10)
    	if err != nil {
    		fmt.Println(a, err)
    	}
    	// 正常情况
    	if result, errorMsg := Divide(100, 10); errorMsg == "" {
    		fmt.Println("100/10 = ", result)
    	}
    	// 当除数为零的时候会返回错误信息
    	if _, errorMsg := Divide(1000, 0); errorMsg != "" {
    		fmt.Println("errorMsg is: ", errorMsg)
    	}
    }
    

     

    三、并发

    func say(s string) {
    	for i := 0; i < 5; i++ {
    		time.Sleep(100 * time.Millisecond)
    		fmt.Println(s)
    	}
    
    }
    func sum(s []int, c chan int) {
    	sum := 0
    	for _, v := range s {
    		sum += v
    	}
    	fmt.Println(sum)
    	c <- sum //把sum值发送到通道c
    }
    func main() {
    	//go say("world") //开启新的线程
    	//say("hello")    //主线程,运行可以看到world跟hello打印没有顺序,证明两个同时进行
    	s := []int{7, 2, 8, -9, 4, 0}
    	c := make(chan int)     //默认通道,需要一发一收
    	go sum(s[:len(s)/2], c) //并发计算,里面发送信号到通道c
    	go sum(s[len(s)/2:], c) //并发
    	x, y := <-c, <-c        //这里接收c的通信
    	fmt.Println(x, y, x+y)
    	//如果构建通道时,给与缓存,可以一次性多发送,再一次性多接收
    	// 因为 ch 是带缓冲的通道,我们可以同时发送两个数据
    	// 而不用立刻需要去同步读取数据
    	ch := make(chan int, 2)
    	ch <- 1
    	ch <- 2
    	u, v := <-ch, <-ch
    	fmt.Println(u, v)
    	ch2 := make(chan int, 10)
    	go fibonacci(cap(ch2), ch2)
    	// range 函数遍历每个从通道接收到的数据,因为 c 在发送完 10 个
    	// 数据之后就关闭了通道,所以这里我们 range 函数在接收到 10 个数据
    	// 之后就结束了。如果上面的 c 通道不关闭,那么 range 函数就不
    	// 会结束,从而在接收第 11 个数据的时候就阻塞了。
    	for i := range ch2 {
    		fmt.Println(i)
    	}
    
    }
    func fibonacci(n int, c chan int) {
    	x, y := 0, 1
    	for i := 0; i < n; i++ {
    		c <- x
    		x, y = y, x+y
    	}
    	close(c)
    }
    

      

    四、总结

      go语言接口方面设计确实很简洁,实现接口里的方法只要对应的结构体实现。错误处理看起来只是简单的方法调用。并发上确实简单,调用时直接加go关键词,就会新开线程同步执行。还有关于通信接收,还只是初步了解,默认情况下通道只有1,接收要同步,一发一收,否则就会阻塞形成死锁。如果给通道设置容量,可以多发多收。接触了go语言,确实在一方面有突出的点。接着会学习goweb的开发!

  • 相关阅读:
    图片的下方与父元素有间隙兼容性解决方案
    vscode 实用插件
    给网页title前面上图标
    网站换肤
    基于面向对象编程的设计模式
    点击获取验证码进行60秒倒计时
    JVM--内存模型与线程
    JVM学习--jvm监控和故障处理工具
    JVM--GC学习
    JVM--Java类加载机制
  • 原文地址:https://www.cnblogs.com/zrl66/p/14075389.html
Copyright © 2011-2022 走看看