使用一个具有标量或切片的函数。

huangapple go评论82阅读模式
英文:

Use a function with a scalar or slice

问题

我想使用函数T_conv来处理浮点数或浮点数切片。以下是使用浮点数作为T_conv参数的示例代码:

func T_conv(T ...interface{}) []interface{} {
    var r []interface{} = make([]interface{}, len(T))
    for i, v := range T {
        fmt.Printf("Ind: %d Result: %v, type: %T\n", i, v, v)
        r[i] = v.(float64) * 1.00024
    }
    return r
}

func main() {
    v := T_conv(20.0)
    fmt.Printf("Result: %v, type: %T\n", v, v)
}

但是,当使用切片作为参数时,在运行时会出现错误:

func main() {
    v := T_conv([]float64{20.0, 21.0})
    fmt.Printf("Result: %v, type: %T\n", v, v)
}

错误信息为:
Ind: 0 Result: [20 21], type: []float64
panic: interface conversion: interface is []float64, not float64

你可以在这里查看完整的示例代码:http://play.golang.org/p/3DP96EamxW

英文:

I would like use the function T_conv with a float or a slice of float.
This example works with float as argument of T_conv:

func T_conv(T ...interface{}) []interface{} {
	var r []interface{} = make([]interface{}, len(T))
	for i, v := range T {
		fmt.Printf("Ind: %d Result: %v, type: %T\n", i, v, v)
		r[i] = v.(float64) * 1.00024
	}
	return r
}

func main() {
	v := T_conv(20.0)
	fmt.Printf("Result: %v, type: %T\n", v, v)
}

http://play.golang.org/p/YhdFoXyY_e

but fail at runtime with a slice as argument:

func main() {
	v := T_conv([]float64{20.0, 21.0})
	fmt.Printf("Result: %v, type: %T\n", v, v)
}

result:
Ind: 0 Result: [20 21], type: []float64
panic: interface conversion: interface is []float64, not float64

http://play.golang.org/p/3DP96EamxW

答案1

得分: 2

你的方法,已修正

在你的情况下,问题在于如果你将一个切片传递给你的 T_conv() 函数,在 T_conv() 内部它将成为 T 切片参数的第一个元素。传递的切片将不会与 T 完全相同。所以如果你想让它正常工作,你必须使用类型断言T[0] 中获取 []float64,然后对其进行迭代。

类似这样:Go Playground

func T_conv(T ...interface{}) []interface{} {
    if len(T) == 0 {
        return []interface{}{}
    }

    if f, ok := T[0].(float64); ok {
        return []interface{}{f * 1.00024}
    } else if fs, ok := T[0].([]float64); ok {
        var r []interface{} = make([]interface{}, len(fs))
        for i, v := range fs {
            r[i] = v * 1.00024
        }
        return r
    }

    return nil
}

但我推荐以下解决方案。

推荐的方法

你的输入问题非常适合使用具有可变参数的函数:

func Conv(in ...float64) []float64 {
    out := make([]float64, len(in))
    for i, v := range in {
        out[i] = v * 1.00024
    }
    return out
}

使用方法:

请注意,在将切片传递给它时,你必须使用 ...。了解更多信息:将参数传递给 ... 参数。你甚至可以通过枚举浮点数(而不是将它们包装在切片中)来调用它。

v := Conv(1.0)
fmt.Printf("Result: %v, type: %T\n", v, v)

v = Conv([]float64{20.0, 21.0}...)
fmt.Printf("Result: %v, type: %T\n", v, v)

v = Conv(20.0, 21.0)
fmt.Printf("Result: %v, type: %T\n", v, v)

输出结果(在 Go Playground 上尝试):

Result: [1.00024], type: []float64
Result: [20.0048 21.00504], type: []float64
Result: [20.0048 21.00504], type: []float64
英文:

Your approach, corrected

The problem in your case is if you pass a slice to your T_conv() function, inside T_conv() it will be the first element of the T slice parameter. The passed slice will not be identical to T. So if you want to make it work, then you have to use Type assertion to obtain the []float64 from T[0], and iterate over that.

Something like this: Go Playground

func T_conv(T ...interface{}) []interface{} {
    if len(T) == 0 {
        return []interface{}{}
    }

    if f, ok := T[0].(float64); ok {
        return []interface{}{f * 1.00024}
    } else if fs, ok := T[0].([]float64); ok {
        var r []interface{} = make([]interface{}, len(fs))
        for i, v := range fs {
            r[i] = v * 1.00024
        }
        return r
    }

    return nil
}

But I recommend the following solution.

Your input problem is a perfect use-case for a function with variadic parameters:

func Conv(in ...float64) []float64 {
	out := make([]float64, len(in))
	for i, v := range in {
		out[i] = v * 1.00024
	}
	return out
}

Using it:

Note that you have to use ... when passing a slice to it. Read more: Passing arguments to ... parameters. You can even invoke it by enumerating the float numbers (without wrapping them in a slice).

v := Conv(1.0)
fmt.Printf("Result: %v, type: %T\n", v, v)

v = Conv([]float64{20.0, 21.0}...)
fmt.Printf("Result: %v, type: %T\n", v, v)

v = Conv(20.0, 21.0)
fmt.Printf("Result: %v, type: %T\n", v, v)

Output (try it on the Go Playground):

Result: [1.00024], type: []float64
Result: [20.0048 21.00504], type: []float64
Result: [20.0048 21.00504], type: []float64

huangapple
  • 本文由 发表于 2015年8月18日 21:26:03
  • 转载请务必保留本文链接:https://go.coder-hub.com/32073755.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定