在各種程式語言(例如Haskell)中,fmap 是將函數應用於資料結構同時保留其類型的寶貴工具。然而,由於其基於方法的泛型,在 Go 中實現 fmap 的直接等效項提出了獨特的挑戰。問題出現了:我們如何在不影響型別安全的情況下模擬 Go 中的 fmap 功能?
Go 泛型的限制
不幸的是,Go 目前的泛型系統並不適合自己透過方法直接模擬 fmap。方法參數無法引入新的類型參數,導致問題中提到的類型不匹配錯誤。
替代方法
雖然使用類似的方法可能很誘人對於Haskell 來說,以下考慮因素導致了更明智的選擇:
fmap 作為頂層函數
在 Go 中模擬 fmap 的建議方法是將其定義為任何類型之外的頂級函數。以下是一個例子:
package main import "fmt" type S[A any] struct { contents A } func Fmap[A, B any](sa S[A], f func(A) B) S[B] { return S[B]{contents: f(sa.contents)} } func main() { ss := S[string]{"foo"} f := func(s string) int { return len(s) } fmt.Println(Fmap(ss, f)) // {3} }
這種方法與 Go 的基於方法的泛型更好地保持一致,同時保持類型安全性和可讀性。
結論
儘管將其他語言的概念直接翻譯成 Go 可能很誘人,但考慮 Go 語言固有的局限性很重要。透過採用更慣用的基於 Go 的方法來模擬 fmap,我們可以在遵循 Go 的設計原則的同時實現所需的功能。
以上是我們如何在保持型別安全的同時模擬 Go 中的 fmap 功能?的詳細內容。更多資訊請關注PHP中文網其他相關文章!