亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

將無符號字節流轉換為有符號字節流 Golang

將無符號字節流轉換為有符號字節流 Golang

Go
慕工程0101907 2022-01-10 18:48:31
在 Golang 中將字節流轉換為字節流切片的最佳方法是什么?目前我正在嘗試在 golang 中復制一個 java 程序,我相信我遇到了一些問題,即 java 將字節流讀取為有符號值,而 golang 將其視為無符號值。當我用 Java 打印時,請注意負值是不同的。正面是一樣的:爪哇:8| -8 | -58 |-61|-56|-113|42|16|-64|2|24|-16|1戈朗:8| 248 | 198 |195|200|143|42|16|192|2|2|240|1目前,我在 GO 中的實現如下所示://open the file with os.open//create new reader and unzip it//reads from zip file and returns an array of bytes associated with it.data, err := ioutil.ReadAll(fz)if err != nil {    return nil, err}//reflect.TypeOf shows this is a []uint8//I want this to be a []int8 (so signed). 在 Java 中,實現幾乎是:  //create buffer reader  //create input stream  //create datainput stream  //use the .Read function to get the values required. 我沒有看到任何簡單的方法可以將其快速轉換為有符號的 int(也許我錯了)。我可以嘗試遍歷整個切片,將每個值轉換為有符號整數,但這種方法似乎相當混亂。它還需要我對每個進行操作。有沒有更干凈的方法來轉換切片?
查看完整描述

3 回答

?
慕尼黑的夜晚無繁華

TA貢獻1864條經驗 獲得超6個贊

需要明確的一些事情:Java 和 Go 都以相同的方式從文件中讀取數據。


文件是按 8 位分組的一系列二進制數據,我們稱之為字節。這個字節是 8 位,你如何解釋它完全取決于你。


Go 和 Java 都將讀取相同的 8 位組,但 Java 會將其存儲在byte有符號類型的 Java類型中,而 Go 會將其存儲在無符號的 Gobyte類型中。但是兩者都將具有相同的 8 位,讀取的數據將相等:


var b byte = 248

var i int8 = -8

fmt.Printf("%x %x\n", b, byte(i))

輸出:


f8 f8

如果您需要將讀取的 8 位解釋為有符號值,只需使用類型轉換:


data := []byte{8, 248, 198}

for _, v := range data {

    fmt.Println(int8(v))

}

輸出(與 Java 輸出相同):


8|-8|-58|

試試Go Playground上的示例。


您是否應該擔心性能(因為類型轉換)?絕對不。byte->int8轉換沒有運行時成本,因為兩者具有相同的內存布局(即 8 位 = 1 字節),并且轉換只是告訴以不同的方式解釋這 8 位。


查看完整回答
反對 回復 2022-01-10
?
慕運維8079593

TA貢獻1876條經驗 獲得超5個贊

unsafe.Pointer如果您確切知道自己在做什么,則可以使用。因為顧名思義,它是不安全的。因此,如果您不明智地使用它,它會爆炸。


package main


import (

    "fmt"

    "unsafe"

)


func main() {

    unsigned := make([]uint8, 0)

    unsigned = append(unsigned, 128)

    unsigned = append(unsigned, 255)


    signed := *(*[]int8)(unsafe.Pointer(&unsigned))

    fmt.Printf("%d : %d\n", signed[0], unsigned[0])

    fmt.Printf("%d : %d\n", signed[1], unsigned[1])

}

// -128 : 128

// -1 : 255

你可以在Go 操場上找到這個例子


查看完整回答
反對 回復 2022-01-10
?
喵喔喔

TA貢獻1735條經驗 獲得超5個贊

上面的不安全答案非常好,但是它不適用于appengine。


這是安全版本:


signed := make([]int8, len(unsigned))

for i, v := range unsigned {

    signed[i] = int8(v)

}


查看完整回答
反對 回復 2022-01-10
  • 3 回答
  • 0 關注
  • 350 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號