- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
我有一个函数可以解决 Go 不允许在方法声明中设置默认值的问题。我想通过允许可变数量的返回变量来让它变得更好一点。我知道我可以允许接口(interface)数组作为返回类型,然后创建一个接口(interface)数组,其中包含要返回的所有变量,如下所示:
func SetParams(params []interface{}, args ...interface{}) (...[]interface{}) {
var values []interface{}
for i := range params {
var value interface{}
paramType := reflect.TypeOf(params[i])
if len(args) < (i + 1) {
value = params[i]
} else {
argType := reflect.TypeOf(args[i])
if paramType != argType {
value = params[i]
}
value = args[i]
}
values = append(values, value)
}
return values
}
这是您要为其定义默认值的方法示例。您将其构建为可变参数函数(允许可变数量的参数),然后在函数内部而不是在声明行中定义您要查找的特定参数的默认值。
func DoSomething(args ...interface{}) {
//setup default values
str := "default string 1"
num := 1
str2 := "default string 2"
//this is fine
values := SetParams([]interface{str, num, str2}, args)
str = values[0].(string)
num = values[1].(int)
str = values[2].(string)
//I'd rather support this
str, num, str2 = SetParams(params, args)
}
我明白了
[]interface{str, num, str2}
在上面的例子中语法不正确。我这样做是为了简化我的帖子。但是,它代表了另一个构建接口(interface)数组的函数。
我愿意支持这个:
str, num, str2 = SetParams(params, args)
不必这样做:
values := SetParams([]interface{str, num, str2}, args)
str = values[0].(string)
num = values[1].(int)
str = values[2].(string)
有什么建议吗?帮忙?
最佳答案
请不要编写可怕的(由于 reflect
而无效)的代码来解决不存在的问题。正如评论中指出的那样,将一种语言变成你以前的一种语言确实很有说服力切换后,但这会适得其反。
相反,最好使用习语和方法以及该语言提供的最佳实践——即使您不喜欢它们(现在,也许)。
对于这种特殊情况,您可以像这样滚动:
制作想要接受的函数具有默认值的参数列表接受自定义 struct
类型的单个值。
首先,分配此类类型的任何变量时,它的所有字段都用所谓的“零值”初始化适合各自的类型。
如果够了,你可以到此为止:你将能够将您的 struct
类型的值传递给您的函数通过在调用站点通过文字生成它们——仅初始化您需要的字段。
否则有预处理/后处理代码将为字段提供您自己的“零值”你需要。
2016-08-29 更新:
使用struct
类型来模拟可选参数使用其字段被分配默认值发生成为各自数据类型的 Go 原生零值:
package main
import (
"fmt"
)
type params struct {
foo string
bar int
baz float32
}
func myfun(params params) {
fmt.Printf("%#v\n", params)
}
func main() {
myfun(params{})
myfun(params{bar: 42})
myfun(params{foo: "xyzzy", baz: 0.3e-2})
}
输出:
main.params{foo:"", bar:0, baz:0}
main.params{foo:"", bar:42, baz:0}
main.params{foo:"xyzzy", bar:0, baz:0.003}
如你所见,Go 初始化了我们的 params
类型的字段具有适合其各自类型的零值除非我们在定义文字时指定我们自己的值。
提供不是 Go-native 零值的默认值我们自定义类型的字段可以通过或对用户提交的复合类型值进行后处理。
后处理:
package main
import (
"fmt"
)
type params struct {
foo string
bar int
baz float32
}
func (pp *params) setDefaults() {
if pp.foo == "" {
pp.foo = "ahem"
}
if pp.bar == 0 {
pp.bar = -3
}
if pp.baz == 0 { // Can't really do this to FP numbers; for demonstration purposes only
pp.baz = 0.5
}
}
func myfun(params params) {
params.setDefaults()
fmt.Printf("%#v\n", params)
}
func main() {
myfun(params{})
myfun(params{bar: 42})
myfun(params{foo: "xyzzy", baz: 0.3e-2})
}
输出:
main.params{foo:"ahem", bar:-3, baz:0.5}
main.params{foo:"ahem", bar:42, baz:0.5}
main.params{foo:"xyzzy", bar:-3, baz:0.003}
预处理相当于创建一个“构造函数”这将返回预填充的所需类型的值使用您为其字段选择的默认值——某物像这样:
func newParams() params {
return params{
foo: "ahem",
bar: -3,
baz: 0.5,
}
}
这样你函数的调用者就可以调用newParams()
,如果需要,调整其字段,然后传递结果值到你的功能:
myfunc(newParams())
ps := newParams()
ps.foo = "xyzzy"
myfunc(ps)
这种方法可能比后处理更稳健,但它排除了使用文字来构造要传递给的值您的功能就在不太“整洁”的调用站点。
关于go - 在方法声明中允许可变数量的返回值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39177189/
为什么禁用类型像 type t = A of int | B of string * mutable int 虽然允许此类类型: type t = A of int | B of string * i
我正在寻找一种类似结构的数据结构,我可以从中创建多个实例并具有某种类型提示而不是不可变的。 所以我有这样的东西: class ConnectionConfig(NamedTuple): nam
我需要转到引用的结构: class SearchKnot { var isWord : Bool = false var text : String = "" var to
如sec 10.4.3中所述 当控制进入执行时,执行以下步骤 功能对象F(调用者)中包含的功能代码的上下文 提供thisArg,而调用方提供argumentsList: 如
i make a game that start display Activity indicator And activity indicator bottom display UiLable wi
编辑:我在这里不断获得支持。只是为了记录,我认为这不再重要。自从我发布它以来我就不再需要它了。 我想在 Scala 中执行以下操作... def save(srcPath: String, destP
使用可变对象作为 Hashmap 键是一种不好的做法吗?当您尝试使用已修改足以更改其哈希码的键从 HashMap 中检索值时,会发生什么? 例如,给定 class Key { int a; /
如果您在Kotlin中访问List类型的Java值,则将获得(Mutable)List!类型。 例如。: Java代码: public class Example { public stati
我编写了 str 类(内置)的以下扩展,以便执行以下操作:假设我有字符串 "Ciao" ,通过做"Ciao" - "a"我想要的结果是字符串 "Cio" 。这是执行此操作的代码,并且运行良好: cla
使用可变对象作为 Hashmap 键是一种不好的做法吗?当您尝试使用已修改足以更改其哈希码的键从 HashMap 中检索值时,会发生什么? 例如,给定 class Key { int a; /
我正在为我的公司设计一个数据库来管理商业贷款。每笔贷款都可以有担保人,可以是个人或公司,在借款业务失败时作为财务支持。 我有 3 个表:Loan、Person 和 Company,它们存储明显的信息。
我使用二进制序列化从 C# 类中保存 F# 记录。一切正常: F#: type GameState = { LevelStatus : LevelStatus
import javax.swing.JOptionPane; public class HW { public static void main(String[] args) { Strin
使用 flatbuffer mutable 有多少性能损失? 是否“正确”使用 FlatBuffers 来拥有一个应该可编辑的对象/结构(即游戏状态) 在我的示例中,我现在有以下类: class Ga
std::function create_function (args...) { int x = initial_value (args...); return [x] () mut
我需要在 for 循环中找到用户输入的字符。我通常会这样做 如果(句子[i] == 'e') 但是因为在这里,'e' 将是一个单字母字符变量,我不知道如何获取要比较的值。我不能只输入 if (sent
我有一个这样的算法: let seed: Foo = ... let mut stack: Vec = Vec::new(); stack.push(&seed); while let Some(ne
这个问题可能看起来非常基础,但我很难弄清楚如何做。我有一个整数,我需要使用 for 循环来循环整数次。 首先,我尝试了—— fn main() { let number = 10; // An
如果我有以下结构: struct MyStruct { tuple: (i32, i32) }; 以及以下函数: // This will not compile fn function(&mut s
我希望在每个 session 的基础上指定列的默认值。下面的脚本不起作用,但描述了我想如何使用它。我目前使用的是 MySQL 5.5.28,但如果需要可以升级。 CREATE TABLE my_tbl
我是一名优秀的程序员,十分优秀!