2014-01-05 41 views
4

我正在嘗試學習接口,以及如何編寫單個函數以使用不同類型。我想出了這個例子,我在int片或float32片中找到最大值。代碼如下。我不斷收到這個錯誤「t不是一種類型」。有人能告訴我什麼是錯的,我可能會如何解決它?Golang反映包「不是一個類型」

package main 

import "fmt" 
import "reflect" 

var _ = fmt.Println 
var _ = reflect.TypeOf 

func maxer(s interface{}) interface{} { 
    v := reflect.ValueOf(s) 
    t := v.Type() 

    maxval := s.(t)[0] 
    for _, v := range s.(t)[1:] { 
     if v > maxval { 
      maxval = v 
     } 
    } 
    return maxval 
} 

func main() { 
    fmt.Println(maxer([]int{1, 2, 3, 4})) 
    fmt.Println(maxer([]float32{1.1, 2.1, 3.14, 0.1, 2.4})) 
+1

'v.Type()'是描述類型,而不是一個類型,因此'第(t)的一個對象'沒有定義。 –

回答

1

我想你最終需要在這種情況下手動處理不同的類型。 AFAIK,類型斷言在編譯時必須是真實的類型。這是我的最佳嘗試:http://play.golang.org/p/J8RdHF2MVV

1

我正在嘗試學習接口以及如何編寫單個函數以使用不同類型。

那麼避免整個反射包可能會更簡單,並且只爲您的特定目的定義一個接口..以及實現您的接口的類型。像這樣:

package main 

import "fmt" 
import "math" 


// Homegrown types 
type IntArray []int 
type Float32Array []float32 


// Max defined for type IntArray 
func (a IntArray) Max() float64 { 
    max := math.MinInt32; 
    for i := 0; i < len(a); i++ { 
     if a[i] > max { 
      max = a[i] 
     } 
    } 
    return float64(max) 
} 


// Max defined for type Float32Array 
func (a Float32Array) Max() float64 { 
    max := float32(-1 * math.MaxFloat32) 
    for i := 0; i < len(a); i++ { 
     if a[i] > max { 
      max = a[i] 
     } 
    } 
    return float64(max) 
} 


// Define an interface that works for any type 
// containing a Max function returning a float64 
type Maxing interface { 
    Max() float64 
} 


// Define a function that works with your interface type 
func maxer(m Maxing) float64 { 
    return m.Max(); 
} 


func main(){ 

    // Declare a new IntArray 
    i := IntArray([]int{1,2,3}) 

    // Declare a new Float32Array 
    f := Float32Array([]float32{1.0,2.0,3.0}) 

    // Use any type implementing the Max interface with the 'maxer' func 
    fmt.Printf("maxer(IntArray)  = %f\n", maxer(i)); 
    fmt.Printf("maxer(Float32Array) = %f\n", maxer(f)); 

} 
0

bjarneh's response類似。如果你想通過接口來做到這一點,最好避免反思。反映並不適合比較值,因爲您無法知道值的類型。

我的建議是實施類似go's sort interface的東西,它允許您使用任何類型的函數sort。

通過這種方式實現它可以讓您獲得結構或字符串的最大值,只要您爲它們實現了函數即可。

On go playgorund

package main 

import (
    "fmt" 
) 

type Comparable interface { 
    Less(i, j int) bool 
    Len() int 
    Val(i int) interface{} 
} 

func maxer(s Comparable) (interface{}) { 
    if s.Len() == 0 { 
     return nil 
    } 
    maxI := 0 
    for i := 1; i < s.Len(); i++ { 
     if s.Less(maxI, i) { 
      maxI = i 
     } 
    } 
    return s.Val(maxI) 
} 

type MaxerInt []int 
func (m MaxerInt) Len() int {return len(m)} 
func (m MaxerInt) Val(i int) interface{} {return m[i]} 
func (m MaxerInt) Less(i, j int) bool {return m[i] < m[j]} 

type MaxerFloat []float64 
func (m MaxerFloat) Len() int {return len(m)} 
func (m MaxerFloat) Val(i int) interface{} {return m[i]} 
func (m MaxerFloat) Less(i, j int) bool {return m[i] < m[j]} 

func main() { 
    fmt.Println(maxer(MaxerInt{1, 2, 3, 4})) 
    fmt.Println(maxer(MaxerFloat{1.1, 2.1, 3.14, 0.1, 2.4})) 
}