• [go]interface


    interface基础

    //介绍和定义
      接口定义来对象的行为规范, 只定义,不实现
      具体的对象实现规范细节
    
    //接口是一组方法签名的集合
    type Animal interface {
    	Talk()
    	Eat() int
    	Run()
    }
    
    //一个对象只要包含接口中的所有方法,那么就实现来这个接口
    //接口类型的变量, 可以保存具体类型的实例
    type people interface {
    	say()
    }
    
    type user struct {
    }
    
    func (u user) say() {
    	fmt.Println("user say")
    }
    
    func main() {
    	var u user
    
    	var p people
    	p = u
    	p.say()
    }
    
    //接口应用实例
    1.公司每个部门员工都有计算薪水的方法,但是计算方法不同
    2.日志输入console,文件等方式
    
    //空接口和类型断言
    // 空接口没有定义任何方法
    type A interface {
    
    }
    
    func main() {
    	var a A
    }
    
    //接口类型实例值是nil
    func main() {
    	var a interface{}
    	fmt.Println(a)
    }
    
    //<nil>
    
    func main() {
    	var a interface{} = 10
    	fmt.Println(a)
    }
    
    //10
    
    //空接口可以存任意类型的值
    func main() {
    	var a interface{}
    
    	b:=1
    	c:=false
    	a = b
    	fmt.Println(a)
    	a = c
    	fmt.Println(a)
    }
    
    //1
    //false
    
    //空接口类型作为map的key: 可接收任意类型的值
    //空接口类型作为函数的参数: 可接收任意类型的值
    func test(a interface{}) {
    	fmt.Println(a)
    }
    func main() {
    	test(1)
    	test(false)
    }
    
    //1
    //false
    
    //获取接口类型里具体的值
    
    func test(i interface{}) {
    	s := i.(int) //get the underlying int value from i
    	fmt.Println(s)
    }
    
    func main() {
    	var a interface{} = 10
    	test(a)
    }
    
    //10
    
    //获取接口类型存储的值
    
    func test(i interface{}) {
    	s := i.(int) //get the underlying int value from i
    	fmt.Println(s)
    }
    
    func main() {
    	var a interface{} = "hel"
    	test(a)
    }
    
    //panic: interface conversion: interface {} is string, not int
    
    // 类型断言: ok机制: 判断空接口里存储的类型
    
    func test(i interface{}) {
    	v, ok := i.(int) //get the underlying int value from i
    	if ok {
    		fmt.Println(v)
    	}
    }
    
    func main() {
    	var a interface{} = "hel"
    	test(a)
    }
    
    //类型断言: switch
    func test(i interface{}) {
    	switch i.(type) {
    	case int:
    		fmt.Println(i.(int))
    	case string:
    		fmt.Println(i.(string))
    	default:
    		fmt.Println("unkown type")
    	}
    }
    
    func main() {
    	var a interface{} = 10
    	test(a)
    
    	var b interface{} = "hi"
    	test(b)
    }
    
    //10
    //hi
    

    interface使用例子

    //日志库例子: 没有接口约束的情况
    
    type ConsoleLog struct {
    }
    
    func NewConsoleLog() *ConsoleLog {
    	return &ConsoleLog{}
    }
    
    func (c *ConsoleLog) LogConsoleDebug(msg interface{}) {
    	fmt.Println(msg)
    }
    
    type FileLog struct {
    }
    
    func NewFileLog() *FileLog {
    	return &FileLog{}
    }
    
    func (c *FileLog) LogFileDebug(msg interface{}) {
    	fmt.Println(msg)
    }
    
    func main() {
    	console := NewConsoleLog()
    	console.LogConsoleDebug("console: test log")
    
    	file := NewFileLog()
    	file.LogFileDebug("file: test log")
    }
    
    //日志库例子: 有接口约束的情况, 切换log更加方便
    
    type LogInterface interface {
    	Debug(msg interface{})
    }
    
    type ConsoleLog struct {
    }
    
    func NewConsoleLog() LogInterface { //返回类型是接口
    	return &ConsoleLog{}
    }
    
    func (c *ConsoleLog) Debug(msg interface{}) {
    	fmt.Println(msg)
    }
    
    type FileLog struct {
    }
    
    func NewFileLog() LogInterface {
    	return &FileLog{}
    }
    
    func (c *FileLog) Debug(msg interface{}) {
    	fmt.Println(msg)
    }
    
    func main() {
    	log := NewConsoleLog()
    	log.Debug("console: test log")
    
    	log = NewFileLog()
    	log.Debug("file: test log")
    }
    

    输出日志

    //输出日志到console
    msg := fmt.Sprintf(format, args...) //format里的坑  args解出的数据相匹配
    fmt.Fprintf(os.Stdout, "%s
    ", msg)
    
    
    //输出日志到文件
    file, _ := os.OpenFile("/tmp/test.log", os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0755)
    fmt.Fprintf(file, "name: %s
    ", "maotai")
    

    异步写日志

    //将日志写入chan
    select {
    case f.LogDataChan <- logData:
    default:
    }
    
    //从chan中去除日志写到文件
    for logData := range f.LogDataChan {
        fmt.Fprintf(file, "%s %s (%s:%s:%d) %s
    ", logData.TimeStr, logData.LevelStr, logData.Filename, logData.FuncName, logData.LineNo, logData.Message)
    }
    
    //写日志核心逻辑
    
    func main() {
    	ch := make(chan int, 10)
    	//异步写日志
    
    	//读日志
    	go func() {
    		for v := range ch {
    			fmt.Println(v)
    		}
    	}()
    
    	for {//防止子协程退出
    		select {
    		case ch <- 1:
    		default: //管道满了则丢弃日志,防止程序夯住
    		}
    		time.Sleep(time.Second)
    	}
    }
    
    
  • 相关阅读:
    has already been called for this response
    Mysql Innodb的两种表空间方式
    针对MyISAM表锁的解决方案
    MySQL数据库表修复--MyISAM
    如何修复损坏的MySQL数据表[转]
    MySQL大量unauthenticated user
    Linux基本命令篇 进程管理
    Linux 知识点滴
    Linux基本命令篇 用户管理
    Linux基本命令篇 文件管理
  • 原文地址:https://www.cnblogs.com/iiiiiher/p/12005041.html
Copyright © 2020-2023  润新知