中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Golang數據類型實例代碼比較分析

發布時間:2023-04-18 10:15:46 來源:億速云 閱讀:131 作者:iii 欄目:開發技術

這篇文章主要講解了“Golang數據類型實例代碼比較分析”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“Golang數據類型實例代碼比較分析”吧!

分類說明是否能比較說明
基本類型整型( int/uint/int8/uint8/int16/uint16/int32/uint32/int64/uint64/byte/rune等)浮點數( float32/float64)復數類型( complex64/complex128)字符串( string)
引用類型切片(slice)、map
聚合類型(復合類型)數組相同長度的數組可以比較,不同長度的數組不能進行比較

結構體只包含可比較的類型情況下可比較
接口類型如error

 基本數據類

  • 類型一致且是基本類型,值相等的時候,才能==

  • 非基本類型會panic panic: runtime error: comparing uncomparable type []int

浮點比較

不過基本類型中也要注意浮點型的比較就不像我們現實中的一樣,比如0.1+0.2在計算中運行結果就不是0.3了,而是0.30000000000000004了

package main import "fmt" func main() {     
    var a float64=0.1     
    var b float64=0.2     
    // 0.30000000000000004     
    fmt.Println(a+b) 
}

字符串比較

一般的比較運算符(==、!=、<、<=、>=、>)是通過在內存中按字節比較來實現字符串比較的,因此比較的結果是字符串自然編碼的順序。字符串所占的字節長度可以通過函數 len() 來獲取,例如 len(str)

比較兩個字符是否相等

package golangbase

import (
	"fmt"
	"testing"
)

func TestString(t *testing.T) {
	str1 := "哈哈"
	str2 := "哈哈"
	fmt.Println(str1 == str2)
}

輸出結果為true

引用類型

slice、map

  • 切片之間不允許比較。切片只能與nil值比較

  • map之間不允許比較。map只能與nil值比較

  • 兩個nil也不能比較,會panic

slice、map比較

使用reflect.DeepEqual()

對比規則

  • 相同類型的值是深度相等的,不同類型的值永遠不會深度相等。

  • 當數組值(array)的對應元素深度相等時,數組值是深度相等的。

  • 當結構體(struct)值如果其對應的字段(包括導出和未導出的字段)都是深度相等的,則該值是深度相等的。

  • 當函數(func)值如果都是零,則是深度相等;否則就不是深度相等。

  • 當接口(interface)值如果持有深度相等的具體值,則深度相等。

  • 當切片(slice)序號相同,如果值,指針都相等,那么就是深度相等的

  • 當哈希表(map)相同的key,如果值,指針都相等,那么就是深度相等的。

使用示例

package golangbase

import (
	"reflect"
	"testing"
)

type StructA struct {
	Name  string
	Hobby []string
}

type StructB struct {
	Name string
}

func TestDeepEqual(t *testing.T) {
	s1 := StructA{Name: "test", Hobby: []string{"唱", "跳"}}
	s2 := StructA{Name: "test", Hobby: []string{"唱", "跳"}}
	println(reflect.DeepEqual(s1, s2))// true
	mp1 := map[int]int{1: 10, 2: 20}
	mp2 := map[int]int{1: 10, 2: 20}
	println(reflect.DeepEqual(mp1, mp2))// true
}

channel、指針

指針可比較,只要指針指向的地址一樣,則相等

由于通過make創建channel后,返回的是一個指針,所以可以比較

c1 := make(chan int, 2) 
 
c2 := make(chan int, 2) 
 
c3 := c1 
 
fmt.Println(c3 == c1) // true 
 
fmt.Println(c2 == c1) // false

聚合類型

數組

數組在go中是必須先確定長度的,也就是長度不能再去擴容。并且它是個值拷貝,做參數傳到一個函數中被修改,那么外部的值還是一樣的不變的。Slice則相反。那么數組是否可以比較呢,看下面的例子:

package main
import "fmt"
func main() {
    a := [2]int{1, 2}
    b := [2]int{1, 2}
    c := [2]int{1, 3}
    d := [3]int{1, 2, 4}
    fmt.Println(a == b) // true
    fmt.Println(a == c) // false
    fmt.Println(a == d) // invalid operation: a == d (mismatched types [2]int and [3]int)
}

可以看出,相同長度的數組是可以比較的,而不同長度的數組是不能進行比較的。原因是什么呢?這是因為數組類型中,數組的長度也是類型的一部分,不同長度的數組那么他們的類型也就被認為不同的,所以無法比較

結構體

只包含可比較的類型情況下可比較

package main
import "fmt"
type A struct {
    id int
    name string
}
func main() {
    a := A{id:5,name:"123"}
    b := A{id:5,name:"123"}
    c := A{id:5,name:"1234"}
    fmt.Println(a == b) // true
    fmt.Println(a == c) // false
}

反例,因為slice不可比較,如果結構體包含了slice,則不可比較

package main
import "fmt"
type A struct {
    id int
    name string
    son []int
}
func main() {
    a := A{id:5,name:"123",son:[]int{1,2,3}}
    b := A{id:5,name:"123",son:[]int{1,2,3}}
    fmt.Println(a == b) // invalid operation: a == b (struct containing []int cannot be compared)
}

接口

Go 語言根據接口類型是否包含一組方法將接口類型分成了兩類:

  • 使用 runtime.iface結構體表示包含方法的接口

  • 使用 runtime.eface結構體表示不包含任何方法的 interface{} 類型

type eface struct { // 16 字節
    _type *_type
    data  unsafe.Pointer
}

type iface struct { // 16 字節
    tab  *itab
    data unsafe.Pointer
}

一個接口值是由兩個部分組成的,即該接口對應的類型和接口對應具體的值

接口值的比較涉及這兩部分的比較,只有當類型和值都相等(動態值使用==比較),兩個接口值才是相等的。看個例子:

var a interface{} = 0
var b interface{} = 2
var c interface{} = 0
var d interface{} = 0.0
fmt.Println(a == b) // false
fmt.Println(a == c) // true
fmt.Println(a == d) // false

a和c類型相同(都是int),值也相同(都是0,基本類型比較),故兩者相等。 a和b類型相同,值不等,故兩者不等。 a和d類型不同,a為int,d為float64,故兩者不等

最后做個練習

func TestJson(t *testing.T) {
	var x, y Data
	x = Data{
		UUID:    "856f5555806443e98b7ed04c5a9d6a9a",
		Content: 1,
	}
	bytes, _ := json.Marshal(x)
	_ = json.Unmarshal(bytes, &y)
	println(x)
	println(y)
	println(reflect.DeepEqual(x, y))
}

為什么結果為false?

debug看一下

Golang數據類型實例代碼比較分析

原因是json.Unmarshal默認會將所有的數字類型轉為float64

Golang數據類型實例代碼比較分析

針對這種情況,可以封裝一個DeepEqual方法

func DeepEqual(v1, v2 interface{}) bool {
	if reflect.DeepEqual(v1, v2) {
		return true
	}
	bytesA, _ := json.Marshal(v1)
	bytesB, _ := json.Marshal(v2)
	return bytes.Equal(bytesA, bytesB)
}

![在這里插入圖片描述](https://img-blog.csdnimg.cn/55d294d1ab7740aba7b547d1a6165b5a.png)

感謝各位的閱讀,以上就是“Golang數據類型實例代碼比較分析”的內容了,經過本文的學習后,相信大家對Golang數據類型實例代碼比較分析這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

冕宁县| 内黄县| 仪征市| 灵宝市| 佛坪县| 永修县| 新乡市| 内黄县| 宁安市| 铜陵市| 浦东新区| 宁津县| 上思县| 民县| 巩留县| 连平县| 定远县| 博乐市| 邵武市| 陇南市| 出国| 仙桃市| 石棉县| 洛隆县| 关岭| 顺平县| 岱山县| 峡江县| 山东省| 大洼县| 呼伦贝尔市| 中山市| 诸暨市| 交口县| 南投市| 象州县| 鞍山市| 盐边县| 盖州市| 兰考县| 会东县|