刻意区分类型(但底层有相同的类型

package main

type Celsius float64    // 摄氏温度
type Fahrenheit float64 // 华氏温度
const (
	AbsoluteZeroC Celsius = -273.15 // 绝对零度
	FreezingC     Celsius = 0       // 结冰点温度
	BoilingC      Celsius = 100     // 沸水温度
)

func CToF(c Celsius) Fahrenheit { return Fahrenheit(c*9/5 + 32) }
func FToC(f Fahrenheit) Celsius { return Celsius((f - 32) * 5 / 9) }

我们在这个包声明了两种类型:Celsius和Fahrenheit分别对应不同的温度单位。它们虽然有 着相同的底层类型float64,但是它们是不同的数据类型,因此它们不可以被相互比较或混在 一个表达式运算。刻意区分类型,可以避免一些像无意中使用不同单位的温度混合计算导致 的错误。

1. 有两种方式来转换

    (1)一个类似Celsius(t)或Fahrenheit(t)形式的显式转型操作才能将float64转为 对应的类型。Celsius(t)和Fahrenheit(t)是类型转换操作,它们并不是函数调用。类型转换不 会改变值本身,但是会使它们的语义发生变化。

    (2)CToF和FToC两个函数则是对不同 温度单位下的温度进行换算,它们会返回不同的值。

对于上面的第一种:每一个类型T,都有一个对应的类型转换操作T(x),用于将x转为T类型(译注:如果T是 指针类型,可能会需要用小括弧包装T,比如 (*int)(0) )。只有当两个类型的底层基础类型 相同时,才允许这种转型操作,或者是两者都是指向相同底层结构的指针类型,这些转换只 改变类型而不会影响值本身。如果x是可以赋值给T类型的值,那么x必然也可以被转为T类 型,但是一般没有这个必要。

2. 运算

底层相同的变量可以进行运算:

	fmt.Printf("%g\n", BoilingC-FreezingC) // "100" °C
	boilingF := CToF(BoilingC)
	fmt.Printf("%g\n", boilingF-CToF(FreezingC)) // "180" °F
	fmt.Printf("%g\n", boilingF-FreezingC) // compile error: type mismatch

3.比较

底层相同的变量可以进行比较:

	var c Celsius
	var f Fahrenheit
	fmt.Println(c == 0) // "true"
	fmt.Println(f >= 0) // "true"
	fmt.Println(c == f) // compile error: type mismatch
	fmt.Println(c == Celsius(f)) // "true"!

4.其他

许多类型都会定义一个String方法,因为当使用fmt包的打印方法时,将会优先使用该类型对 应的String方法返回的结果打印,

func (c Celsius) String() string { return fmt.Sprintf("%g°C", c) }

func main() {
	c := FToC(212.0)
	fmt.Println(c.String()) // "100°C"
	fmt.Printf("%v\n", c) // "100°C"; no need to call String explicitly
	fmt.Printf("%s\n", c) // "100°C"
	fmt.Println(c) // "100°C"
	fmt.Printf("%g\n", c) // "100"; does not call String
	fmt.Println(float64(c)) // "100"; does not call String
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值