”工欲善其事,必先利其器。“—孔子《论语.录灵公》
首页 > 编程 > Go 中类型转换和转换的综合指南

Go 中类型转换和转换的综合指南

发布于2024-08-30
浏览:857

A Comprehensive Guide to Type Casting and Conversions in Go

Go,也称为 Golang,是一种静态类型语言。这意味着每个变量的类型在编译时都是已知的,从而为代码提供安全性和可预测性。但是,这也要求从一种类型到另一种类型的任何转换都是明确且经过深思熟虑的。在本文中,我们将探讨 Go 中可用的各种类型转换和转换机制,从基本的数值转换到更复杂的接口和指针转换。

1. 基本类型转换

Go 允许在整数、浮点数和字符串等基本类型之间进行转换,但这些转换必须显式完成。

数字类型

不同数字类型之间的转换很简单,但必须明确:

var i int = 42
var f float64 = float64(i)  // int to float64
var u uint = uint(i)        // int to uint

在此示例中,我们将 int 转换为 float64 和 uint。这些转换是显式的,因为 Go 不执行自动(隐式)类型转换。

字符串和字节切片

Go 字符串是不可变的,但它们可以与字节切片 ([]byte) 相互转换,而字节切片 ([]byte) 是可变的:

var s string = "hello"
var b []byte = []byte(s)   // string to []byte
var s2 string = string(b)  // []byte to string

同样,可以在字符串和符文切片([]rune)之间进行转换,其中符文是 int32 的类型别名:

var r []rune = []rune(s)   // string to []rune
var s3 string = string(r)  // []rune to string

2. 自定义类型转换

在Go中,您可以基于现有类型定义自己的类型。自定义类型与其基础类型之间的转换是显式的:

type MyInt int
var i int = 10
var mi MyInt = MyInt(i)   // int to MyInt
var i2 int = int(mi)      // MyInt to int

此显式转换对于确保编译器可以验证代码的安全性是必要的。

3. 指针转换

Go中的指针引用变量的内存地址。您可以在值与其指针之间进行转换:

var x int = 42
var p *int = &x     // int to *int (pointer to int)
var y int = *p      // *int to int (dereferencing)

4. 接口类型转换

Go中的接口用于定义一组方法。您可以在具体类型和接口之间进行转换:

var a interface{} = 42    // int to interface{}
var b int = a.(int)       // interface{} to int (type assertion)

类型断言

类型断言提供对接口具体值的访问:

if v, ok := a.(int); ok {
    fmt.Println("a is an int:", v)
}

类型开关

类型开关允许您根据接口的动态类型执行不同的操作:

switch v := a.(type) {
case int:
    fmt.Println("a is an int:", v)
case string:
    fmt.Println("a is a string:", v)
default:
    fmt.Println("a is of unknown type")
}

5. 不安全的转换

unsafe 包允许你绕过 Go 的类型安全,从而实现非法的转换:

import "unsafe"

var i int = 42
var p *int = &i
var fp *float64 = (*float64)(unsafe.Pointer(p))  // *int to *float64

警告:应谨慎使用不安全的转换,并且仅在绝对必要时使用,因为它们可能导致未定义的行为。

6. 通道类型转换

通道是 Go 中的一个强大功能,允许 goroutine 之间进行通信。您可以在双向和单向通道之间进行转换:

ch := make(chan int)
var sendOnlyChan chan



7. 结构体和数组转换

具有相同布局的结构体或数组之间的转换需要显式转换:

type Point struct {
    X, Y int
}

type Coord struct {
    X, Y int
}

var p Point = Point{1, 2}
var c Coord = Coord(p)  // Convert Point to Coord (same field types)

8. 切片转换

切片是对数组的引用,虽然您可以在相同类型的切片之间进行转换,但不同类型的切片之间的转换需要显式转换:

var a []int = []int{1, 2, 3}
var b []int = a[1:]  // Convert a slice to another slice of the same type

9. 零接口转换

Go 中的 nil 值可以分配给任何接口类型:

var x interface{} = nil
var y error = nil

10. 函数类型转换

Go 函数可以转换为不同类型,只要签名兼容:

type FuncType func(int) int

func square(x int) int {
    return x * x
}

var f FuncType = FuncType(square)  // Convert function to FuncType

11. 数组到切片的转换

可以从数组创建切片,它本质上是对数组的引用:

var arr [5]int = [5]int{1, 2, 3, 4, 5}
var sl []int = arr[:]  // Convert array to slice

结论

Go 中的类型转换和转换在设计上是明确的,使代码更安全、更容易理解。通过要求显式转换,Go 有助于防止隐式类型强制可能产生的微妙错误,这在其他一些编程语言中很常见。理解这些转换并正确使用它们对于编写健壮且高效的 Go 程序至关重要。

版本声明 本文转载于:https://dev.to/zakariachahboun/a-comprehensive-guide-to-type-casting-and-conversions-in-go-26di?1如有侵犯,请联系[email protected]删除
最新教程 更多>
  • 如何从Python中的字符串中删除表情符号:固定常见错误的初学者指南?
    如何从Python中的字符串中删除表情符号:固定常见错误的初学者指南?
    从python import codecs import codecs import codecs 导入 text = codecs.decode('这狗\ u0001f602'.encode('utf-8'),'utf-8') 印刷(文字)#带有...
    编程 发布于2025-04-05
  • 可以在纯CS中将多个粘性元素彼此堆叠在一起吗?
    可以在纯CS中将多个粘性元素彼此堆叠在一起吗?
    [2这里: https://webthemez.com/demo/sticky-multi-header-scroll/index.html </main> <section> { display:grid; grid-template-...
    编程 发布于2025-04-05
  • 在程序退出之前,我需要在C ++中明确删除堆的堆分配吗?
    在程序退出之前,我需要在C ++中明确删除堆的堆分配吗?
    在C中的显式删除 在C中的动态内存分配时,开发人员通常会想知道是否有必要在heap-procal extrable exit exit上进行手动调用“ delete”操作员,但开发人员通常会想知道是否需要手动调用“ delete”操作员。本文深入研究了这个主题。 在C主函数中,使用了动态分配变量(H...
    编程 发布于2025-04-05
  • 如何在Java的全屏独家模式下处理用户输入?
    如何在Java的全屏独家模式下处理用户输入?
    Handling User Input in Full Screen Exclusive Mode in JavaIntroductionWhen running a Java application in full screen exclusive mode, the usual event ha...
    编程 发布于2025-04-05
  • 如何使用Python有效地以相反顺序读取大型文件?
    如何使用Python有效地以相反顺序读取大型文件?
    在python 中,如果您使用一个大文件,并且需要从最后一行读取其内容,则在第一行到第一行,Python的内置功能可能不合适。这是解决此任务的有效解决方案:反向行读取器生成器 == ord('\ n'): 缓冲区=缓冲区[:-1] ...
    编程 发布于2025-04-05
  • 哪种在JavaScript中声明多个变量的方法更可维护?
    哪种在JavaScript中声明多个变量的方法更可维护?
    在JavaScript中声明多个变量:探索两个方法在JavaScript中,开发人员经常遇到需要声明多个变量的需要。对此的两种常见方法是:在单独的行上声明每个变量: 当涉及性能时,这两种方法本质上都是等效的。但是,可维护性可能会有所不同。 第一个方法被认为更易于维护。每个声明都是其自己的语句,使其...
    编程 发布于2025-04-05
  • 如何使用Python的请求和假用户代理绕过网站块?
    如何使用Python的请求和假用户代理绕过网站块?
    如何使用Python的请求模拟浏览器行为,以及伪造的用户代理提供了一个用户 - 代理标头一个有效方法是提供有效的用户式header,以提供有效的用户 - 设置,该标题可以通过browser和Acterner Systems the equestersystermery和操作系统。通过模仿像Chro...
    编程 发布于2025-04-05
  • 为什么PHP的DateTime :: Modify('+1个月')会产生意外的结果?
    为什么PHP的DateTime :: Modify('+1个月')会产生意外的结果?
    使用php dateTime修改月份:发现预期的行为在使用PHP的DateTime类时,添加或减去几个月可能并不总是会产生预期的结果。正如文档所警告的那样,“当心”这些操作的“不像看起来那样直观。 考虑文档中给出的示例:这是内部发生的事情: 现在在3月3日添加另一个月,因为2月在2001年只有2...
    编程 发布于2025-04-05
  • 如何处理PHP文件系统功能中的UTF-8文件名?
    如何处理PHP文件系统功能中的UTF-8文件名?
    在PHP的Filesystem functions中处理UTF-8 FileNames 在使用PHP的MKDIR函数中含有UTF-8字符的文件很多flusf-8字符时,您可能会在Windows Explorer中遇到comploreer grounder grounder grounder gro...
    编程 发布于2025-04-05
  • 您如何在Laravel Blade模板中定义变量?
    您如何在Laravel Blade模板中定义变量?
    在Laravel Blade模板中使用Elegance 在blade模板中如何分配变量对于存储以后使用的数据至关重要。在使用“ {{}}”分配变量的同时,它可能并不总是最优雅的解决方案。幸运的是,Blade通过@php Directive提供了更优雅的方法: $ old_section =“...
    编程 发布于2025-04-05
  • 如何干净地删除匿名JavaScript事件处理程序?
    如何干净地删除匿名JavaScript事件处理程序?
    删除匿名事件侦听器将匿名事件侦听器添加到元素中会提供灵活性和简单性,但是当要删除它们时,可以构成挑战,而无需替换元素本身就可以替换一个问题。 element? element.addeventlistener(event,function(){/在这里工作/},false); 要解决此问题,请考虑...
    编程 发布于2025-04-05
  • Android如何向PHP服务器发送POST数据?
    Android如何向PHP服务器发送POST数据?
    在android apache httpclient(已弃用) httpclient httpclient = new defaulthttpclient(); httppost httppost = new httppost(“ http://www.yoursite.com/script.p...
    编程 发布于2025-04-05
  • 如何配置Pytesseract以使用数字输出的单位数字识别?
    如何配置Pytesseract以使用数字输出的单位数字识别?
    Pytesseract OCR具有单位数字识别和仅数字约束 在pytesseract的上下文中,在配置tesseract以识别单位数字和限制单个数字和限制输出对数字可能会提出质疑。 To address this issue, we delve into the specifics of Te...
    编程 发布于2025-04-05
  • 如何同步迭代并从PHP中的两个等级阵列打印值?
    如何同步迭代并从PHP中的两个等级阵列打印值?
    同步的迭代和打印值来自相同大小的两个数组使用两个数组相等大小的selectbox时,一个包含country代码的数组,另一个包含乡村代码,另一个包含其相应名称的数组,可能会因不当提供了exply for for for the uncore for the forsion for for ytry...
    编程 发布于2025-04-05
  • 为什么我会收到MySQL错误#1089:错误的前缀密钥?
    为什么我会收到MySQL错误#1089:错误的前缀密钥?
    mySQL错误#1089:错误的前缀键错误descript [#1089-不正确的前缀键在尝试在表中创建一个prefix键时会出现。前缀键旨在索引字符串列的特定前缀长度长度,可以更快地搜索这些前缀。了解prefix keys `这将在整个Movie_ID列上创建标准主键。主密钥对于唯一识别...
    编程 发布于2025-04-05

免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。

Copyright© 2022 湘ICP备2022001581号-3