zoukankan      html  css  js  c++  java
  • [golang] go的typeswitch guard(类型区别)语法和type assertion(类型断言)语法

    最近在实现golang,看到个go的特性语法: typeswitch guard。

    typeswitch guard语法如下:

    package main
    
    import "fmt"
    
    func typeChecking(p interface{}) {
    
    	switch p.(type) {
    	case int:
    		fmt.Print("int")
    	case float64:
    		fmt.Printf("float64")
    	}
    }
    
    func main(){
    	typeChecking(56.67)
            typeChecking(56)
    }
    

    运行时判断p的类型,并根据是什么类型进行对应操作,较之与其他语言比如java的连续if else在语法上要美观一些:

    if(p instance of TypeA){
        System.out.println("Type A");
    }else if (p instance of TypeB){
        System.out.println("Type B");
    }...
    

    另外需要注意它的参数只能是interface,因为其他类型都可以被编译器编译时type inference,只有interface具有运行时类型。

    最后可以看到,类型区别语法和类型断言很像的,仅在于p.(X)括号内不是type关键字而是类型。
    如果类型正确那么程序正常,如果类型错误则panic

    func typeAssertion(p interface{}){
    	q:=p.(int)
    	fmt.Print(q)
    }
    
    func main(){
    	typeAssertion(5.7)
    }
    

    上述例子如果p的类型是int,那么正常输出;如果不是则painc。

    既然实现golang,就多说一点点
    typeswitch 在golang 1.11对应的ast 结构如下:

    TypeSwitchGuard struct {
    	Lhs *Name // nil means no Lhs :=
    	X   Expr  // X.(type)
    	expr
    }
    

    也就是说typeswitch guard其实是有两种语法的:

    X.(type)
    Lhs := X.(type)
    

    我们可以将typeswitch guard的值赋给一个变量,变量的值相当于p本身的值:

    func typeChecking(p interface{}) {
    
    	switch q :=p.(type) {
    	case int:
    		fmt.Print("int")
    	case float64:
    		fmt.Print(q)
    		fmt.Printf("float64")
    	}
    }
    
    func main(){
    	typeChecking(56.67)
    }
    

    最后输出

    56.67float64
    

    前面说到它的语法和type assertion也非常类似,这是有原因的。编译器区分两者仅在于p.(X)括号内是否为关键字type

    			case _Lparen:
    				p.next()
    				if p.got(_Type) {//如果括号内是关键字type则是typeswitch,否则便是type assertion
    					t := new(TypeSwitchGuard)
    					// t.Lhs is filled in by parser.simpleStmt
    					t.pos = pos
    					t.X = x
    					x = t
    				} else {
    					t := new(AssertExpr)
    					t.pos = pos
    					t.X = x
    					t.Type = p.type_()
    					x = t
    				}
    				p.want(_Rparen)
    
  • 相关阅读:
    Django
    from appium import webdriver 报错
    myEclipse下Maven配置操作
    Spring框架实现——远程方法调用RMI代码演示
    普通方法实现——远程方法调用RMI代码演示
    Spring转账业务_注解配置事物控制
    Spring转账业务_XML配置事物控制
    Spring通过XML方式实现定时任务
    Spring通过注解方式实现定时任务
    IDEA使用操作文档
  • 原文地址:https://www.cnblogs.com/ysherlock/p/9794542.html
Copyright © 2011-2022 走看看