【Go语言圣经2.5】

打印 上一主题 下一主题

主题 904|帖子 904|积分 2712

目标

了解类型界说不仅告诉编译器怎样在内存中存储和处置惩罚数据,还对步伐计划产生深远影响:


  • 内存结构:类型决定了变量的底层存储(好比占用多少字节、内存布局等)。
  • 操作符与方法集:类型决定了哪些内置运算符适用于它,以及可否为该类型界说方法,从而扩展它的行为。
  • 语义区分:通过界说新类型,纵然它们的底层类型雷同,也能明确区分不同概念,制止混用(例如温度单位、索引、文件描述符等)。
  • 可读性与安全性:使用定名类型可以让代码语义更明确,从而低落出错的风险。
概念


  • 每个变量或表达式都有一个类型,类型描述了值的属性,如数据占用的内存巨细、内部结构、支持哪些操作以及关联的方法集等。
  • 一个 int 类型的变量可能用于表现索引、时间戳或月份;一个 float64 类型的变量可能表现速率或温度。只管底层都是数字,但语义上却截然不同。
  • 内存与数据表现:每个数据类型在内存中的表现方式(如整数占用 32 位或 64 位)由其底层类型决定。定名类型会沿用雷同的存储方式,但在类型体系中赋予它新的含义。
  • 方法与吸收者

    • **方法的界说:**在 Go 中,可以为任意定名类型界说方法,使得该类型的值具有特定行为(如格式化输出)。
    • 调用示例:fmt.Printf 等函数会自动调用类型的 String 方法,从而定制输出格式。
    • 静态分派:fmt.Printf 等函数会自动调用类型的 String 方法,从而定制输出格式。

要点

类型声明语句

  1. type 新类型名称 底层类型
复制代码
这条语句创建一个新的类型名称,其底层结构与现有类型雷同,但在类型体系中被以为是不同的。例如:
  1. type Celsius float64    // 摄氏温度类型
  2. type Fahrenheit float64 // 华氏温度类型
复制代码
纵然 Celsius 和 Fahrenheit 都基于 float64,它们是两个不同的类型,防止你无意中混用不同温度单位的数据。


  • 定名规则与导出

    • 假如新类型名称的首字符大写,则表现该类型对包外可见(导出)。
    • Go 语言中关于 Unicode 字母的规则也使得中文定名默认不能导出(Go 1 的规则),但在将来的 Go 2 中可能会调解。

  • 用途

    • 语义区分:通过界说不同的定名类型(纵然底层雷同)可以让步伐更安全,不会将代表不同概念的值误用在一起。
    • 简化代码:对于复杂或冗长的类型,用一个简单的名称可以使代码更清楚易读。

类型转换操作


  • 操作形式
    类型转换写作 T(x),它不会改变 x 的实际值,只是将它“贴上”新的类型标签
    1. var f Fahrenheit = CToF(BoilingC)
    2. fmt.Println(Celsius(f)) // 将 f 转换为 Celsius 类型
    复制代码

    • 限制:只有当两个类型的底层类型完全雷同时,大概都是指向雷同底层结构的指针时,才能举行转换。

  • 作用
    通过类型转换,可以将同样底层数据但语义不同的值显式转换,使得运算和比较变得类型安全。例如
    1. var c Celsius
    2. var f Fahrenheit
    3. // c == f // 编译错误:类型不匹配
    4. fmt.Println(c == Celsius(f)) // 显式转换后可以比较
    复制代码
类型与方法


  • 方法集
    定名类型不仅是一个新的数据类型,还可以为该类型界说方法,这使得它拥有特定的行为。
    1. func (c Celsius) String() string {
    2.     return fmt.Sprintf("%g°C", c)
    3. }
    复制代码
    这段代码为 Celsius 类型界说了一个 String 方法,在调用 fmt.Printf 时会自动调用该方法来格式化输出。(由于 fmt 包会自动调用 String 方法)(详细一点说:当一个类型实现了 String() string 方法后,它就满足了 fmt 包界说的 Stringer 接口。fmt 包在格式化输出时,会检查传入的值是否实现了该接口,假如实现了,就自动调用 String() 方法来获取该值的字符串表现。)
    1. c := FToC(212.0)
    2. fmt.Println(c.String()) // 输出 "100°C"
    3. fmt.Printf("%v\n", c)   // 也输出 "100°C",因为 fmt 包会自动调用 String 方法
    复制代码
    为类型界说方法不仅增长了代码的可读性,也让类型更具语义。
怎样界说 Celsius 与 Fahrenheit 两个定名类型及它们之间的转换和方法

  1. // Package tempconv performs Celsius and Fahrenheit temperature computations.
  2. package tempconv
  3. import "fmt"
  4. type Celsius float64    // 定义摄氏温度类型
  5. type Fahrenheit float64 // 定义华氏温度类型
  6. // 常量声明
  7. const (
  8.     AbsoluteZeroC Celsius = -273.15 // 绝对零度(摄氏)
  9.     FreezingC     Celsius = 0       // 冰点(摄氏)
  10.     BoilingC      Celsius = 100     // 沸点(摄氏)
  11. )
  12. // CToF 将摄氏温度转换为华氏温度
  13. func CToF(c Celsius) Fahrenheit {
  14.     return Fahrenheit(c*9/5 + 32)
  15. }
  16. // FToC 将华氏温度转换为摄氏温度
  17. func FToC(f Fahrenheit) Celsius {
  18.     return Celsius((f - 32) * 5 / 9)
  19. }
  20. // Celsius 的 String 方法,使其输出更友好
  21. func (c Celsius) String() string {
  22.     return fmt.Sprintf("%g°C", c)
  23. }
复制代码


  • Celsius 类型的 String 方法为其提供了定制格式,当使用 fmt 包打印时,会自动调用此方法。
类型比较与运算



  • 支持内置运算符
    由于 Celsius 和 Fahrenheit 的底层类型都是 float64,所以它们可以使用底层类型的算术和比较运算符。例如:
    1. fmt.Printf("%g\n", BoilingC-FreezingC) // 输出 "100"
    2. boilingF := CToF(BoilingC)
    3. fmt.Printf("%g\n", boilingF-CToF(FreezingC)) // 输出 "180"
    复制代码
    留意,直接将 Fahrenheit 与 Celsius 举行运算会导致编译错误,由于它们是不同的定名类型。
  • 比较运算
    只有雷同类型之间才能举行直接比较:
    1. var c Celsius
    2. var f Fahrenheit
    3. fmt.Println(c == 0)          // "true",0 会被视为 Celsius 类型的零值
    4. fmt.Println(f >= 0)          // "true",同理,0 对于 Fahrenheit 也是零值
    5. // fmt.Println(c == f)       // 编译错误:类型不匹配
    6. fmt.Println(c == Celsius(f)) // 正确:通过类型转换后比较
    复制代码
总结


  • 类型界说描述了变量的内存表现、支持的运算符和方法集,同时区分不同的语义。
  • 将不同的概念界说为不同的定名类型,纵然它们底层雷同,也能在编译期防止错误的混用。(例如,不警惕将温度与文件描述符混用可能引发错误,通过界说不同类型就可以制止这种情况。)
  • 类型转换 T(x) 只改变 x 的类型标签而不改变底层数据。转换要求两个类型有雷同的底层类型或兼容的结构。
  • 方法与类型行为:为定名类型界说方法(如 String 方法),使得在打印和其它操作时可以自动调用,加强了类型的体现力。
  • 新类型继承了底层类型的算术与比较操作,但必须保证操作数类型一致。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

惊落一身雪

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表