zoukankan      html  css  js  c++  java
  • 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.以上是我个人的理解,希望各位没有被我绕糊涂  

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

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

    * 以上内容为作者原创,转载请注明出处。
    -----------------------------------------------------
  • 相关阅读:
    【Lintcode】112.Remove Duplicates from Sorted List
    【Lintcode】087.Remove Node in Binary Search Tree
    【Lintcode】011.Search Range in Binary Search Tree
    【Lintcode】095.Validate Binary Search Tree
    【Lintcode】069.Binary Tree Level Order Traversal
    【Lintcode】088.Lowest Common Ancestor
    【Lintcode】094.Binary Tree Maximum Path Sum
    【算法总结】二叉树
    库(静态库和动态库)
    从尾到头打印链表
  • 原文地址:https://www.cnblogs.com/xiaopipi/p/4889212.html
Copyright © 2011-2022 走看看