问题标签 [go]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
vector - Go 中是否有用于矢量包的 removeElement 函数版本,如 Java 在其 Vector 类中具有的?
我正在将一些 Java 代码移植到 Google 的 Go 语言中,并且我转换了所有代码,除了在一个非常流畅的移植之后我只卡在一个部分上。我的 Go 代码如下所示,我正在谈论的部分已被注释掉:
如果没有可用的版本,我相信没有......有谁知道我将如何自己实施这样的事情?
vector - 在 Google 的 Go 语言中,向量赋值是按值复制还是按引用复制?
在下面的代码中,我创建了一个钉子拼图,然后对其进行移动,将移动添加到它的 moveAlreadyDone 向量中。然后我创建另一个挂钩拼图,然后在其上移动,向它的 moveAlreadyDone 向量添加移动。当我为第二个向量打印出该向量中的值时,它具有从第一个向量的移动以及从第二个向量的移动。谁能告诉我为什么它似乎是通过引用而不是价值分配?在 Google 的 Go 语言中,向量赋值是按值复制还是按引用复制?
任何帮助将不胜感激。谢谢!
interface - 不能在字段值中使用 (*struct) 作为 (*interface)
我有以下代码:
当我尝试编译时,出现以下错误:
如果我将有问题的行注释掉,它会编译并运行良好。这里发生了什么事?我错过了什么?
file - 如何使用 Go 读取/写入文件
我一直在尝试自学 Go,但在尝试读取和写入普通文件时遇到了困难。
我可以达到inFile, _ := os.Open(INFILE, 0, 0)
,但实际上获取文件的内容没有意义,因为 read 函数将 a[]byte
作为参数。
design-patterns - 单例
在 Go 编程语言中如何实现单例设计模式?
dependencies - Go 拒绝未使用依赖项的优缺点
Google 的新语言Go试图通过明确要求实际使用模块中列出的所有依赖项来简化依赖项管理。编译器将拒绝声明对模块的依赖项而不使用该模块中的任何内容的模块。
包自行导入或在不引用任何导出标识符的情况下导入包是非法的。
我可以想到一些明显的优势(例如更清洁的模块),但也许有一些不明显的优势。我能想到的唯一缺点是编译器过于迂腐,在重构过程中抱怨太多,但也许还有更多?
您是否有使用其他语言执行此操作的经验?这种方法的优点和缺点是什么?
loops - 遍历地图的所有键
有没有办法获取 Go 语言映射中所有键的列表?元素的数量由 给出len()
,但如果我有如下地图:
如何遍历所有键?
go - 使用运算符代替函数
是否可以使用运算符代替 go 中的函数?
例如,在下面的代码中是否可以替换add
为+
?
如果无法将运算符用作函数,那么我将不胜感激一个指向澄清这一点的文档的链接。
c++ - Google 的“Go”语言多值返回语句是否可以替代异常?
在我看来,谷歌的例外替代方案是
- GO:多值返回“return val, err;”
- GO,C++:无检查(提前返回)
- GO,C++:“处理该死的错误”(我的术语)
C++:断言(表达式)
GO:defer/panic/recover 是在提出此问题后添加的语言功能
多值回报是否足以作为替代品?为什么“断言”被认为是替代品?如果发生错误处理不正确,Google 是否认为程序停止是可以的?
Go 的一个不同寻常的特性是函数和方法可以返回多个值。这可以用来改进 C 程序中的几个笨拙的习惯用法:带内错误返回(例如 EOF 的 -1)和修改参数。
在 C 语言中,写入错误由负计数表示,错误代码隐藏在易失性位置。在 Go 中,Write 可以返回一个计数和一个错误:“是的,你写了一些字节,但不是全部,因为你填满了设备”。os 包中 *File.Write 的签名为:
func (file *File) Write(b []byte) (n int, err Error)
正如文档所说,它返回写入的字节数和当 n != len(b) 时的非零错误。这是一种常见的风格;有关更多示例,请参见错误处理部分。
Go 函数的返回或结果“参数”可以指定名称并用作常规变量,就像传入参数一样。当命名时,它们在函数开始时被初始化为它们的类型的零值;如果函数执行没有参数的 return 语句,则使用结果参数的当前值作为返回值。
这些名称不是强制性的,但它们可以使代码更短更清晰:它们是文档。如果我们命名 nextInt 的结果,很明显哪个返回的 int 是哪个。
func nextInt(b []byte, pos int) (value, nextPos int) {
因为命名结果被初始化并与一个简单的返回相关联,所以它们可以简化和澄清。这是一个很好地使用它们的 io.ReadFull 版本:
例外是一个类似的故事。已经提出了许多异常设计,但每一种都大大增加了语言和运行时的复杂性。就其本质而言,异常跨越函数,甚至可能跨越 goroutine。它们具有广泛的影响。人们还担心它们会对图书馆产生影响。根据定义,它们是卓越的,但使用其他支持它们的语言的经验表明它们对库和接口规范具有深远的影响。如果能找到一种设计,让它们真正出类拔萃,而又不会鼓励常见错误变成需要每个程序员进行补偿的特殊控制流,那就太好了。
像泛型一样,异常仍然是一个悬而未决的问题。
决定:
从表面上看,使用例外的好处大于成本,尤其是在新项目中。但是,对于现有代码,异常的引入对所有依赖代码都有影响。如果异常可以传播到新项目之外,那么将新项目集成到现有的无异常代码中也会出现问题。由于 Google 现有的大多数 C++ 代码都没有准备好处理异常,因此采用会产生异常的新代码相对困难。
鉴于 Google 现有的代码不能容忍异常,使用异常的成本比新项目的成本要高一些。转换过程会很慢并且容易出错。我们不认为异常的可用替代方法(例如错误代码和断言)会带来很大的负担。
我们反对使用例外的建议不是基于哲学或道德依据,而是基于实际的依据。因为我们想在 Google 使用我们的开源项目,如果这些项目使用异常就很难做到,所以我们也需要建议不要在 Google 开源项目中使用异常。如果我们不得不从头开始重新做一遍,事情可能会有所不同。
Defer 语句允许我们考虑在打开每个文件后立即关闭它,从而保证无论函数中返回语句的数量如何,文件都将被关闭。
defer 语句的行为是直接且可预测的。有三个简单的规则:
1. 当 defer 语句被评估时,延迟函数的参数被评估。
在这个例子中,当 Println 调用被延迟时,表达式“i”被计算。函数返回后,延迟调用将打印“0”。
2. 延迟函数调用在周围函数返回后按后进先出的顺序执行。此函数打印“3210”:
3. 延迟函数可以读取并分配给返回函数的命名返回值。
在此示例中,延迟函数在周围函数返回后递增返回值 i。因此,此函数返回 2:
这样方便修改函数的错误返回值;我们很快就会看到一个例子。
Panic 是一个内置函数,它可以停止普通的控制流程并开始恐慌。当函数 F 调用 panic 时,F 的执行停止,F 中的所有延迟函数都正常执行,然后 F 返回其调用者。对调用者来说,F 的行为就像是对恐慌的调用。该进程继续向上堆栈,直到当前 goroutine 中的所有函数都返回,此时程序崩溃。恐慌可以通过直接调用恐慌来启动。它们也可能是由运行时错误引起的,例如越界数组访问。
Recover 是一个内置函数,可以重新控制恐慌的 goroutine。恢复仅在延迟函数中有用。在正常执行期间,recover 调用将返回 nil 并且没有其他效果。如果当前的 goroutine 正在恐慌,对 recovery 的调用将捕获为 panic 提供的值并恢复正常执行。
这是一个演示恐慌和延迟机制的示例程序:
有关恐慌和恢复的真实示例,请参阅 Go 标准库中的 json 包。它使用一组递归函数对 JSON 编码的数据进行解码。当遇到格式错误的 JSON 时,解析器调用 panic 是将堆栈展开到顶层函数调用,该函数调用会从 panic 中恢复并返回适当的错误值(参见 decode.go 中的 'error' 和 'unmarshal' 函数) . 在 regexp 包的 Compile 例程中有一个类似的技术示例。Go 库中的约定是,即使包在内部使用了 panic,它的外部 API 仍然会显示显式的错误返回值。
defer 的其他用途(除了前面给出的 file.Close() 示例之外)包括释放互斥锁: