2016-10-30 18 views
-3

我已經設法在Go中獲得以下功能。但是我想優化/概括代碼,使得這個函數返回一個指向我傳遞給函數的任何值的第一個字節的指針。目前它只適用於[] uint32,但是我想用它來獲取許多其他類型(即byte [],int [],string等)的起始內存地址作爲*字節。如何獲取Golang中任何數據類型的值的字節指針?

是否有更通用的方法來做到這一點,而不是捕捉我需要解決的每種類型作爲case語句?

去遊樂場鏈接,下面的代碼:https://play.golang.org/p/KtNTbERQGa

package main 

import (
    "fmt" 
    "reflect" 
    "unsafe" 
) 

func ToBytePointer(data interface{}) *byte { 
    fmt.Println("Received type is", reflect.TypeOf(data)) 

    switch data.(type) { 
    case []uint32: 
     typedData := data.([]uint32) 
     return (*byte)(unsafe.Pointer(&typedData[0])) 
    default: 
     return nil 
    } 
} 

func main() { 
    var data = []uint32{1, 2, 3} 
    var dataBytePointer = (*byte)(unsafe.Pointer(&data[0])) 

    fmt.Println(dataBytePointer, ToBytePointer(data)) 
} 
+0

我不認爲這個問題真的可以在沒有定義如何使用'* byte'的情況下得到回答。沒有一個清晰的概念,誰來說什麼是有效的轉換類型?你可以使用['reflect.Value.Pointer'](https://golang.org/pkg/reflect/#Value.Pointer)來解決一些重複的樣板問題。 – nothingmuch

+0

@nothingmuch想想這樣。我希望能夠將起始內存地址獲取到我可以在Go中創建的任何結構。您可以將它與獲取指向C中任何數據類型或結構的指針進行比較。我真正的用法是調用DeviceIoControl方法(Handle,uint32,* byte,uint32,* byte,uint32,* uint32,* Overlapped)。 該方法需要預先初始化的內存緩衝區作爲參數傳遞給它,但是作爲*字節。緩衝區有時由字符串,uint32,[]字節等組成。所以我的目的是創建一個util函數,它給我指向任何底層內存塊的字節指針。 – Neo

+0

使用反射(例如參見reflect.SliceHeader) – thwd

回答

0

Golang沒有仿製藥,所以我想你需要抓住每一個單一類型。

另外,在你的例子中,你得到了slice中第一個元素的第一個字節,而不是傳遞給函數的值的第一個字節。

0

感謝您的建議,我相信我找到了我正在尋找的東西。它可以完成,只需要對Go的反射包進行一點點挖掘即可。我會回答我自己的問題,以便其他人可能會覺得這有幫助。

優雅的一個襯墊,以獲得的任何內存分配塊的起始內存地址爲圍棋一個字節的指針是:

(*byte)(unsafe.Pointer(reflect.ValueOf(anyAllocatedDataGoesHere).Pointer())) 

如果有人需要檢查它的行爲的任何數據類型,即[] uint32,[]字節,字符串,int,結構,看看我準備的這個示例PlayGround。

https://play.golang.org/p/G5fUOCfNCS

+1

你需要知道某個時刻的類型,那麼爲什麼要將該類型隱藏在一個接口中,並且在可以直接轉換指針時使用反射?(以及'string'成爲指向字符串struct的指針,而'[] byte'成爲指向後備數組的指針?「) – JimB

0

根據您的應用是什麼,你可能會考慮採空區編碼或protobuf的(如在布拉德·菲茨的groupcache使用)。你會製作一份你的數據的副本,我很確定仍然有反思,但至少你得到了優化複製&字節編碼,這可能是一個加號,因爲我懷疑一旦你有這些字節的應用程序的下一步是某種類型的副本。

相關問題