Golang类型转换和类型断言

零值

变量声明时没有初始化会默认赋值为零值 。
零值是:

数值类型为 0 
布尔类型为 false 
字符串为 "" (空字符串)

基本类型的类型转换

C语言转换

先看一下,在C语言中的类型转换,
隐式转换

int a = 10;
int b = 3.0
int num = 3.14;  
double res = a/b;

显示转换

int a = 10;
int b = 3.0
double res = (double)a/b;

Golang基本类型间只能进行显示转换

但是,Golang基本类型间只能进行显示转换,
转换形式如下:

Type(value)

其中value是要转换的值(包括变量、复杂算子和函数返回值),Type是要转换成的类型。
在类型转换时,要考虑它们之间的关系和范围,以免精度丢失或数值截断。

特别注意:
byte --> uint8 和 rune --> int32 是能够直接赋值的特殊情况(byte就是unit8的别名,rune就是int32的别名)

看一些例子:

    // 输出各数值范围
    fmt.Println("int8 range:", math.MinInt8, math.MaxInt8)
    fmt.Println("int16 range:", math.MinInt16, math.MaxInt16)
    fmt.Println("int32 range:", math.MinInt32, math.MaxInt32)
    fmt.Println("int64 range:", math.MinInt64, math.MaxInt64)

    // 初始化一个32位整型值
    var a int32 = 1047483647
    // 输出变量的十六进制形式和十进制值
    fmt.Printf("int32: 0x%x %d\n", a, a)

    // 将a变量数值转换为十六进制, 发生数值截断
    b := int16(a)
    // 输出变量的十六进制形式和十进制值
    fmt.Printf("int16: 0x%x %d\n", b, b)

    // 将常量保存为float32类型
    var c float32 = math.Pi
    // 转换为int类型, 浮点发生精度丢失
    fmt.Println(int(c))

bool不能直接转换成整型

bool类型不能强制转换为整型(bool类型在底层是0和1,不能更改为整型变量)

//bool不能直接转换成int,编译器会报错
var flag bool = false
var num int = int(flag) //报错
fmt.Printf("%d\n", num)

string与基本数据类型转换

string-->基本数据类型

  • strconv.ParseXxx()
  • strconv.Atoi()
string-->整型
    /*------strconv.ParseInt------*/

    //十进制
    var str string = "4"
    //转换成int8,int8范围-128~127
    num, err := strconv.ParseInt(str, 10, 8)
    if err != nil {
        fmt.Printf("转换失败\n")
    } else {
        fmt.Printf("%d\n", num)
        fmt.Printf("%T\n", num)
    }

    //十进制
    var str1 string = "233"
    //转换成int8,int8范围-128~127
    num1, err1 := strconv.ParseInt(str1, 10, 8)
    //233超过8位的长度,转换失败
    if err1 != nil {
        fmt.Printf("转换失败\n")
    } else {
        fmt.Printf("%d\n", num1)
        fmt.Printf("%T\n", num1)
    }

    //二进制
    var str2 string = "1001"
    //转换成int32
    num2, err2 := strconv.ParseInt(str2, 2, 32)
    if err2 != nil {
        fmt.Printf("转换失败\n")
    } else {
        fmt.Printf("%d\n", num2)
        fmt.Printf("%T\n", num2)
    }

    /*------strconv.Atoi------*/

    //10进制
    var str3 string = "9" //会转换成功
    //var str string = "9a"   //会转换失败
    num3, err3 := strconv.Atoi(str3)
    if err3 != nil {
        fmt.Printf("转换失败\n")
    } else {
        fmt.Printf("%d\n", num3)
        fmt.Printf("%T\n", num3)
    }
string-->浮点型
    var str string = "3.1234567890123456789"
    num, err := strconv.ParseFloat(str, 32)
    if err != nil {
        fmt.Printf("转换失败\n")
    } else {
        fmt.Println(num)
        fmt.Printf("%T\n", num)
    }
string-->布尔型
    //str的值可以是1、t、T、TRUE、true、True,
    //也可以是0、f、F、FALSE、false、False
    var str string = "F"
    //直接传入字符串
    flag, err := strconv.ParseBool(str)
    if err != nil {
        fmt.Printf("转换失败\n")
    } else {
        // 注意点: 在Go语言中%t输出布尔类型
        fmt.Printf("%t\n", flag) //false
        fmt.Printf("%T\n", flag) //bool
    }

基本数据类型-->string

  • strconv.FormatXxx()
  • strconv.iota()
整型-->string
    /*------strconv.FormatInt------*/

    var num int = 724
    //转换为10进制格式
    str := strconv.FormatInt(int64(num), 10)
    fmt.Printf("十进制:%s\n", str) //输出:724
    //转换为2进制格式
    str2 := strconv.FormatInt(int64(num), 2)
    fmt.Printf("二进制:%s\n", str2) //输出:1011010100
    //转换为16进制格式
    str16 := strconv.FormatInt(int64(num), 16)
    fmt.Printf("十六进制:%s\n", str16) //输出:2d4

    /*------strconv.Itoa------*/

    var num4 int32 = 724
    var str7 string = strconv.Itoa(int(num4))
    fmt.Printf("十进制:%s\n", str7) //输出:724
浮点型-->string
    var num2 float32 = 3.1234567890123456789
    var str3 string = strconv.FormatFloat(float64(num2), 'f', -1, 32) // "3.1234567"
    var str4 string = strconv.FormatFloat(float64(num2), 'f', -1, 64) // "3.123456789012345" 
    var str5 string = strconv.FormatFloat(float64(num2), 'f', 2, 32)  // "3.12"
    fmt.Printf("%s\n%s\n%s\n", str3, str4, str5)
bool-->string
    var flag bool = false
    var str6 string = strconv.FormatBool(flag)
    fmt.Printf("%s\n", str6) //false

time转换

注意:time不是基本类型,但是为了方便整理也放于此处。

    //获取当前时间戳,纳秒
    nanoSeconds := time.Now().UnixNano()
    fmt.Printf("当前纳秒时间戳:%d\n", nanoSeconds)
    fmt.Printf("%T\n", nanoSeconds)
    //纳秒转毫秒
    fmt.Println(nanoSeconds / 1e6)
    //纳秒转秒
    fmt.Println(nanoSeconds / 1e9)

    //获取当前时间戳,秒
    seconds := time.Now().Unix()
    fmt.Printf("当前秒时间戳:%d\n", seconds)
    fmt.Printf("%T\n", seconds)

    //将纳秒时间戳转换成时间
    t := time.Unix(0, 1573541938000*1e6) //将纳秒转换为 time 类型
    fmt.Printf("时间戳转换成时间格式:%s\n", t.String())

    //时间格式化成string
    formatStr := time.Now().Format("2006-01-02 15:04:05.000")
    fmt.Printf("时间格式化成string:%s\n", formatStr)

    //将年月日转换成时间
    yearTime := time.Date(2014, 1, 7, 5, 50, 4, 123*1e6, time.Local)
    yearUnix := yearTime.UnixNano()
    fmt.Printf("年月日转换成时间秒时间戳:%d\n", yearUnix)
    yearFormat := yearTime.Format("2006-01-02 15:04:05.000")
    fmt.Printf("年月日转换成时间:%s\n", yearFormat)

interface{}类型转换和类型断言

  • 类型转换在编译期完成,包括强制转换(类型间、接口向类型、类型向接口转换)和隐式转换(类型向接口转换)
  • 类型断言在运行时确定,包括安全类型断言和非安全类型断言
    Go语言要求不同类型之间必须做显式的类型转换。但似乎涉及到接口类型时,就会有所不同。

类型断言

//animal 动物
type animal interface {
    //run 跑
    run()
}

//duck 鸭子
type duck struct {
    //name 名称
    name string
    //legNum 腿的数量
    legNum int
}

func newDuck() duck {
    return duck{
        name:   "duck",
        legNum: 2,
    }
}
func (d duck) run() {
    fmt.Printf("在%d,%s跑步用%d条腿\n", time.Now().Unix(), d.name, d.legNum)
}

//cat 猫
type cat struct {
    //name 名称
    name string
    //legNum 腿的数量
    legNum int
}

func newCat() cat {
    return cat{
        name:   "cat",
        legNum: 4,
    }
}
func (c cat) run() {
    fmt.Printf("在%d,%s跑步用%d条腿\n", time.Now().Unix(), c.name, c.legNum)
}

func runWithRecover(a animal) {
    defer func() {
        fmt.Println("end")
        if err := recover(); err != nil {
            fmt.Printf("received panic ,the error is %s\n", err) // 这里的err其实就是panic传入的内容
        }
    }()
    i1 := a.(cat)
    i1.run()
}

//类型断言的方式

//typeAssert 类型断言的方式
func typeAssert() {

    //第一种
    var d animal
    d = newDuck()
    //不安全的类型断言,如果系统检测到不匹配,会在运行时调用内置的panic,抛出异常
    i := d.(duck)
    i.run()
    //由于不安全断言会抛panic
    runWithRecover(d)

    //安全的类型断言。 其中ok为一个bool值, 表征类型转换是否成功; s为返回的int变量,如果失败返回该类型的零值
    if inst, ok := d.(duck); ok {
        inst.run()
    }
    if inst, ok := d.(cat); ok {
        inst.run()
    } else {
        fmt.Printf("assert error,the error is %t\n", ok)
    }

    //第二种,type是关键字 结合switch case使用
    switch inst := d.(type) {

    case duck:

        inst.run()
    case cat:
        inst.run()
    default:

        fmt.Println("unknow")

    }
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,122评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,070评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,491评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,636评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,676评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,541评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,292评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,211评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,655评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,846评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,965评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,684评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,295评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,894评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,012评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,126评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,914评论 2 355

推荐阅读更多精彩内容

  • 1. Go语言数据类型 1.1 数据类型分类 Go语言数据类型大致可以分为两类基础类型,其中就包括了我们最常见的一...
    楚江云阅读 677评论 0 0
  • 环境搭建 Golang在Mac OS上的环境配置 使用Visual Studio Code辅助Go源码编写 VS ...
    陨石坠灭阅读 5,780评论 0 5
  • Golang基础语法 [TOC] 一个大的程序是由很多小的基础构件组成的。变量保存值,简单的加法和减法运算被组合成...
    奶爸撸代码阅读 751评论 0 4
  • 现在人们常说三分天注定,七分靠打拼,其实这句话是不无道理的,但也是不正确的。为何如此说呢?因为任何事情都有不为人所...
    爱读书的陕北大叔阅读 1,379评论 0 13
  • 昨晚上11点多,叶芽还是睡不安稳,不给喝奶就哭,体温39度多,还是给吃了退烧药。 吃药没多久就安稳睡了。睡到今早4...
    青青叶芽阅读 212评论 0 0