• go:interface{}、断言与类型转换


    interface{}可用于向函数传递任意类型的变量,但对于函数内部,该变量仍然为interface{}类型(空接口类型)

    不清楚这点将可能导致错误。如以下代码:

    package main
    import "fmt"
    /*
    **用于输出数组元素
    */
    func echoArray(a interface{}){
      for _,v:=range a{
        fmt.Print(v," ")
      }
      fmt.Println()
      return
    }
    func main(){
      a:=[]int{2,1,3,5,4}
      echoArray(a)
    }
    //以上代码将会报错,因为对于echoArray()而言,a是interface{}类型,而不是[]int类型

    接口类型向普通类型的转换称为类型断言(运行期确定)-------摘自《Go语言的类型转换和类型断言》  http://my.oschina.net/chai2010/blog/161418

    其它参考http://blog.csdn.net/jonnyhsu/article/details/41148753

    所以前面代码中,将echoArray()做如下修改即可:

    func echoArray(a interface{}){
        b,_:=a.([]int)//通过断言实现类型转换
      for _,v:=range b{
        fmt.Print(v," ")
      }
      fmt.Println()
      return
    } 

    -----------------------15/11/8更新---------------------------------

    注意:在使用断言时最好用 

    b,ok:=a.([]int)
    if ok{
        ...
    }
    

    的形式,这样能根据ok的值判断断言是否成功。

    因为断言失败在编译阶段不会报错,所以很可能出现断言失败导致运行错误,而你却迟迟找不到原因(亲身经历)。  

    -----------------------15/11/21更新----------------------------- 

    注意:不同类型变量的运算必须进行显式的类型转换,否者结果可能出错,如下例:

    func main() {
    	var a uint8 = 8
    	c := a * 32
    	fmt.Println(a*32, c)
    	fmt.Println(reflect.TypeOf(c))
    	d := a * 31
    	fmt.Println(a*31, d)
    	fmt.Println(reflect.TypeOf(d))
    	return
    }
    /*	输出:
    **	0 0
    **	uint8
    **	248 248
    **	uint8
    */
    

    a*32的结果为0,原因是uint8可以表示的最大值为255( 1111 1111 ),而a*32的值为256(1 0000 0000 ),舍弃溢出的高位后即为0 

    也就是说,go不自动根据a*32的结果为其赋予合适的类型,而是根据a的类型强制其为uint8,所以最终c 和 d 的类型也为uint8。

    总结:

    1.interface{}使得我们可以向函数传递任意类型的变量;

    2.断言解决在使用interface{}的情况下,空接口类型向普通类型转换的类型转换问题;

    3.普通类型之间的转换最好使用显式的类型转换,否者很可能导致严重的错误。

    4.以上是我个人的理解,希望各位没有被我绕糊涂  

    -----------------------------------------------------

    * 本文是根据自身经验所作,难免存在不合理之处。

    * 以上内容为作者原创,转载请注明出处。
    -----------------------------------------------------
  • 相关阅读:
    【数据分析&数据挖掘】拉格朗日插值法
    【数据分析&数据挖掘】异常值的判断与去除——3σ & 箱线图分析
    集腋成裘-13-git使用-02进阶篇
    饮冰三年-人工智能-Python-30 python开发中常见的错误
    饮冰三年-人工智能-Python-31博客园山寨版
    集腋成裘-12-git使用-01创建库
    饮冰三年-人工智能-Python-27 Django Form组件
    饮冰三年-人工智能-Python-29瀑布流
    饮冰三年-人工智能-Python-28 企业官网(组合搜索)
    使用ExtJs建一个后台界面框架
  • 原文地址:https://www.cnblogs.com/xiaopipi/p/4889212.html
Copyright © 2020-2023  润新知