Go 언어에서 유형 어설션은 인터페이스 유형 변수가 보유한 값이 예상되는 인터페이스 또는 특정 유형을 구현하는지 확인하는 데 사용됩니다. 구문은 "value, ok := x 입니다. (티)". 유형 주장을 통해 수행할 수 있는 작업: 1. i가 nil인지 확인합니다. 2. i에 저장된 값이 특정 유형인지 확인합니다.
이 튜토리얼의 운영 환경: Windows 7 시스템, GO 버전 1.18, Dell G3 컴퓨터.
어설션은 부울 표현식으로 표현된 프로그래밍 용어입니다. 코드를 작성할 때 우리는 항상 몇 가지 가정을 하며, 코드에서 이러한 가정을 포착하기 위해 어설션이 사용됩니다. 주장을 간단히 이해하면 판단을 의미합니다. 따라서 Go에서는 유형 주장을 유형 판단으로 이해할 수 있습니다.
유형 어설션은 인터페이스 유형 변수가 보유한 값이 예상 인터페이스 또는 특정 유형을 구현하는지 확인하기 위해 인터페이스 값에 사용되는 작업입니다.
Go 언어의 유형 어설션 구문 형식은 다음과 같습니다.
value, ok := x.(T)
여기서 x는 인터페이스 유형을 나타내고 T는 특정 유형을 나타냅니다(인터페이스 유형일 수도 있음).
이 어설션 표현식은 x 값(즉, 값)과 부울 값(즉, ok)을 반환합니다. 이 부울 값을 사용하여 x가 T 유형인지 확인할 수 있습니다.
T가 특정 유형, 유형 주장은 x의 동적 유형이 구체적인 유형 T와 같은지 확인합니다. 검사가 성공하면 유형 어설션은 유형이 T인 x의 동적 값을 반환합니다.
T가 인터페이스 유형인 경우 유형 어설션은 x의 동적 유형이 T를 충족하는지 확인합니다. 검사가 성공하면 x의 동적 값은 추출되지 않으며 반환 값은 T 유형의 인터페이스 값입니다.
T 유형이 무엇이든 x가 nil 인터페이스 값이면 유형 어설션이 실패합니다.
Go
Variable.(type)
에는 두 가지 주요 유형 어설션 형식이 있습니다. 예: i.(int)变量.(类型)
。例如:i.(int)
变量,bool = 变量.(类型)
。例如:num,ok = i.(int)。ok表示判断类型是否成功的意思。
类型断言的用法
通过类型断言可以做到以下几件事情
检查 i
是否为 nil
检查 i
存储的值是否为某个类型
具体的使用方式有两种:
第一种:
t := i.(T)
这个表达式可以断言一个接口对象(i)里不是 nil,并且接口对象(i)存储的值的类型是 T,如果断言成功,就会返回值给 t,如果断言失败,就会触发 panic。
来写段代码试验一下
package main import "fmt" func main() { var i interface{} = 10 t1 := i.(int) fmt.Println(t1) fmt.Println("=====分隔线=====") t2 := i.(string) fmt.Println(t2) }
运行后输出如下,可以发现在执行第二次断言的时候失败了,并且触发了 panic
10 =====分隔线===== panic: interface conversion: interface {} is int, not string goroutine 1 [running]: main.main() E:/GoPlayer/src/main.go:12 +0x10e exit status 2
如果要断言的接口值是 nil,那我们来看看也是不是也如预期一样会触发panic
package main func main() { var i interface{} // nil var _ = i.(interface{}) }
输出如下,确实是会 触发 panic
panic: interface conversion: interface is nil, not interface {} goroutine 1 [running]: main.main() E:/GoPlayer/src/main.go:5 +0x34 exit status 2
第二种
t, ok:= i.(T)
和上面一样,这个表达式也是可以断言一个接口对象(i)里不是 nil,并且接口对象(i)存储的值的类型是 T,如果断言成功,就会返回其类型给 t,并且此时 ok 的值 为 true,表示断言成功。
如果接口值的类型,并不是我们所断言的 T,就会断言失败,但和第一种表达式不同的事,这个不会触发 panic,而是将 ok 的值设为 false ,表示断言失败,此时t 为 T 的零值。
稍微修改下上面的例子,如下
package main import "fmt" func main() { var i interface{} = 10 t1, ok := i.(int) fmt.Printf("%d-%t\n", t1, ok) fmt.Println("=====分隔线1=====") t2, ok := i.(string) fmt.Printf("%s-%t\n", t2, ok) fmt.Println("=====分隔线2=====") var k interface{} // nil t3, ok := k.(interface{}) fmt.Println(t3, "-", ok) fmt.Println("=====分隔线3=====") k = 10 t4, ok := k.(interface{}) fmt.Printf("%d-%t\n", t4, ok) t5, ok := k.(int) fmt.Printf("%d-%t\n", t5, ok) }
运行后输出如下,可以发现在执行第二次断言的时候,虽然失败了,但并没有触发了 panic。
10-true =====分隔线1===== -false =====分隔线2===== <nil> - false =====分隔线3===== 10-true 10-true
上面这段输出,你要注意的是第二个断言的输出在-false
之前并不是有没有输出任何 t2 的值,而是由于断言失败,所以 t2 得到的是 string 的零值也是 ""
,它是零长度的,所以你看不到其输出。
如果需要区分多种类型,可以使用 type switch 断言,这个将会比一个一个进行类型断言更简单、直接、高效。
package main import "fmt" func findType(i interface{}) { switch x := i.(type) { case int: fmt.Println(x, "is int") case string: fmt.Println(x, "is string") case nil: fmt.Println(x, "is nil") default: fmt.Println(x, "not type matched") } } func main() { findType(10) // int findType("hello") // string var k interface{} // nil findType(k) findType(10.23) //float64 }
输出如下
10 is int hello is string <nil> is nil 10.23 not type matched
额外说明一下:
case nil
변수, bool = 변수.(유형)
. 예: num,ok = i.(int). ok는 유형이 성공했는지 확인하는 것을 의미합니다. i 여부를 확인하세요 code>는 nil입니다🎜🎜🎜🎜<code>i
에 저장된 값이 특정 유형인지 확인하세요🎜🎜🎜🎜이를 사용하는 구체적인 방법은 두 가지가 있습니다.🎜🎜🎜첫 번째 방법:🎜🎜rrreee 🎜this 표현식은 인터페이스 객체(i)가 nil이 아니며 인터페이스 객체(i)에 저장된 값의 유형이 T라고 주장할 수 있습니다. 주장이 성공하면 값이 t로 반환됩니다. 실패하면 패닉이 발생합니다. 🎜🎜테스트할 코드를 작성해 보겠습니다🎜rrreee🎜실행 후 출력은 다음과 같습니다. 두 번째 Assertion이 실패하고 패닉이 발생한 것을 확인할 수 있습니다.🎜rrreee🎜Assertion할 인터페이스 값이 nil이면 다음을 수행합니다. 살펴보세요. 예상대로 패닉🎜rrreee🎜이 발생합니까? 출력은 다음과 같습니다. 실제로 패닉🎜rrreee🎜🎜을 발생시킵니다. 두 번째 유형🎜🎜rrreee🎜도 위와 동일합니다. 객체(i)는 nil이 아니며 인터페이스 객체(i)에 저장된 값의 유형은 T입니다. Assertion이 성공하면 해당 유형이 t로 반환되며 이때 ok 값은 true입니다. , 어설션이 성공했음을 나타냅니다. 🎜🎜인터페이스 값의 유형이 우리가 주장한 T가 아닌 경우 주장은 실패하지만 첫 번째 표현식과 달리 패닉을 유발하지 않지만 ok 값을 false로 설정하여 주장 실패를 나타냅니다. 이번에는 t가 T의 0 값입니다. 🎜🎜위 예제를 다음과 같이 약간 수정합니다. 🎜rrreee🎜실행 후 출력은 다음과 같습니다. 두 번째 Assertion이 실행되었을 때 실패했지만 패닉이 발생하지 않은 것을 확인할 수 있습니다. 🎜rrreee🎜위 출력에서 -false
이전의 두 번째 Assertion의 출력은 t2 출력 값이 있는지 여부가 아니라 Assertion이 실패했기 때문에 t2가 문자열의 0 값도 ""
이므로 길이가 0이므로 출력을 볼 수 없습니다. 🎜case nil
입니다.🎜🎜값이 switch-case Match가 아닌 경우 해당 유형을 선택한 다음 기본 브랜치를 선택하세요🎜🎜🎜[관련 권장 사항: 🎜Go 비디오 튜토리얼🎜, 🎜프로그래밍 교육🎜]🎜위 내용은 Go 언어에서 유형 주장이란 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!