Go中的惯用语类型转换

时间:2012-11-13 20:10:31

标签: go

我正在玩Go,并想知道在Go中执行惯用类型转换的最佳方法是什么。基本上我的问题在uint8uint64float64之间进行自动类型转换。根据我使用其他语言的经验,uint8uint64的乘法将产生uint64值,但在go中则不然。

这是我构建的一个示例,我问这是否是编写此代码的惯用方法,或者我是否缺少重要的语言构造。

package main

import ("math";"fmt")

const(Width=64)

func main() {

    var index uint32
    var bits uint8

    index = 100
    bits = 3

    var c uint64
    // This is the line of interest vvvv
    c = uint64(math.Ceil(float64(index * uint32(bits))/float64(Width)))
    fmt.Println("Test: %v\n", c)
}

从我的观点来看,由于所有显式类型转换,上限值的计算似乎不必要复杂。

谢谢!

3 个答案:

答案 0 :(得分:6)

非常量值没有隐式类型转换。

你可以写

var x float64
x = 1

但你不能写

var x float64
var y int

y = 1
x = y

请参阅the spec以供参考。

有一个很好的理由,不允许自动/隐式类型转换 变得非常混乱,必须学习许多规则来规避各种警告 可能会发生。以Integer Conversion Rules in C为例。

答案 1 :(得分:1)

例如,

package main

import "fmt"

func CeilUint(a, b uint64) uint64 {
    return (a + (b - 1)) / b
}

func main() {
    const Width = 64
    var index uint32 = 100
    var bits uint8 = 3
    var c uint64 = CeilUint(uint64(index)*uint64(bits), Width)
    fmt.Println("Test:", c)
}

输出:

Test: 5

答案 2 :(得分:1)

要添加到@nemo出色的答案。 C语言中的数字类型之间自动转换的便利性被它引起的混乱所笼罩。参见https://Golang.org/doc/faq#conversions。这就是为什么您甚至不能隐式将int转换为int32的原因。参见https://stackoverflow.com/a/13852456/12817546

package main

import (
    . "fmt"
    . "strconv"
)

func main() {
    i := 71
    c := []interface{}{byte(i), []byte(string(i)), float64(i), i, rune(i), Itoa(i), i != 0}
    checkType(c)
}

func checkType(s []interface{}) {
    for k, _ := range s {
        Printf("%T %v\n", s[k], s[k])
    }
}

byte(i)创建一个值为71的uint8,[]byte(string(i))一个带有[71]的[] uint8,float64(i) float64 71,i int 71,{{1 }} int32 71,rune(i)字符串71和Itoa(i)是布尔型,其值为true。

由于Go不会自动为您转换数字类型(请参见https://stackoverflow.com/a/13851553/12817546),因此必须手动在类型之间进行转换。参见https://stackoverflow.com/a/41419962/12817546。注意,Itoa(i)设置“整数到ASCII”。参见https://stackoverflow.com/a/10105983/12817546中的评论。