Golang中缀方法、运算符及实现思路探讨
Golang中缀方法、运算符及实现思路探讨 我知道我不该把这个发在Go论坛上,但我不知道该发在哪里,而且我也不知道如何提建议,因为我只是个编程新手……
我理解操作符重载会增加语言的复杂性,但是像中缀方法这样的功能会不会是一个可行的替代方案呢?
例如,如果你想将两个向量相加,你可以声明一个像这样的方法:
@infix
+#m(matrix: a, matrix:b) matrix {…}
或者,如果你想将一个向量乘以一个标量:
@infix
*#vs(vector: a, float: b) vector {…}
优点:避免了你正在操作什么的歧义,像操作符一样是中缀的,所以流程很自然。 缺点:看起来像■■■■
你们怎么看?很抱歉把这篇帖子发在这里。
更多关于Golang中缀方法、运算符及实现思路探讨的实战教程也可以访问 https://www.itying.com/category-94-b0.html
感谢您的回复和欢迎。
是的,我想在这里讨论这个可能对在 Go 语言中加入这个特性没什么帮助,但我只是把这当作一个头脑风暴环节……
至于如何实现,也许应该分配一个特殊字符,例如在这些用户希望可以写成中缀形式的函数调用开头使用 ‘^’ 或 ‘#’(是的,我改变了前提,哈哈)。这样,当在代码中看到这些表达式时,就能知道这是一个正在以中缀形式使用的函数,并且它恰好接受一个在前和一个在后的参数。也许用逗号分隔它们会更清晰。
例如:
@infixable // 允许你使用中缀表示法
fn add_mat(m1: matrix, m2: matrix) matrix { ... }
@infixable // 编译错误(中缀形式只允许2个参数)
fn foo(int x) void { ... }
fn main() {
let mT = add_mat(m1, m2)
let m2T = m1, #add_mat, m2 // m2T == mT
let m3T = m1, #add_mat, m2, #add_mat, m3 // 以此类推
let m4T = add_mat(add_mat(m1, m2), m3) // 与上面的比较
}
更多关于Golang中缀方法、运算符及实现思路探讨的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
嗨,@gorilla_sama,欢迎来到论坛!
完全不必道歉;[技术讨论]似乎是讨论新功能的好地方。不过我要告诉你,这个论坛里的大多数常驻发帖者都不是Go语言团队的成员,所以即使我们同意你的观点,我们也没有权力为这门语言添加任何新功能。
话虽如此,我搜索了一下什么是“中缀方法”,并且我怀疑Go永远不会有这个功能。我看到Kotlin中使用了它们,我在这里找到了一个描述:
2. 什么是中缀表示法?
Kotlin允许在不使用句点和括号的情况下调用某些函数。这些被称为中缀方法,它们的使用可以使代码看起来更像自然语言。
这在内联Map定义中最常见:
map( 1 to "one", 2 to "two", 3 to "three" )“to” 看起来可能像一个特殊的关键字,但在这个例子中,这是一个利用了中缀表示法的 to() 方法,它返回一个 Pair<A, B>。
我不太认同的是最后一点关于“to”看起来像特殊关键字的说法。除了Go之外,我熟悉的其他语言,比如C#和Python,可能还有Kotlin,似乎都专注于让代码看起来更具声明性,就像代码应该解释它正在做什么,而不是如何做。Go更像是这种理念的对立面,它更喜欢原始的循环和简单的语言结构,来展示某些代码做什么以及如何工作。
在Go语言中,目前没有中缀方法或运算符重载的直接支持。Go的设计哲学强调简洁性和可读性,因此避免了这类特性,以减少语言的复杂性和潜在的混淆。不过,你可以通过结构体方法来实现类似的功能,虽然语法上不是中缀形式,但逻辑上可以达到相同的目的。
以下是一个示例,展示如何通过结构体方法实现向量相加和标量乘法:
package main
import "fmt"
// 定义向量结构体
type Vector struct {
X, Y float64
}
// 向量相加的方法(非中缀形式)
func (v Vector) Add(other Vector) Vector {
return Vector{v.X + other.X, v.Y + other.Y}
}
// 向量乘以标量的方法(非中缀形式)
func (v Vector) Scale(scalar float64) Vector {
return Vector{v.X * scalar, v.Y * scalar}
}
func main() {
v1 := Vector{1.0, 2.0}
v2 := Vector{3.0, 4.0}
// 向量相加
sum := v1.Add(v2)
fmt.Printf("向量相加: %+v\n", sum) // 输出: 向量相加: {X:4 Y:6}
// 向量乘以标量
scaled := v1.Scale(2.0)
fmt.Printf("向量乘以标量: %+v\n", scaled) // 输出: 向量乘以标量: {X:2 Y:4}
}
在这个示例中,我们定义了Vector结构体,并使用Add和Scale方法来实现向量运算。虽然这不是中缀语法,但通过方法调用,代码意图清晰,符合Go的惯用风格。
Go社区通常更倾向于这种显式的方法调用,因为它减少了歧义,提高了代码的可维护性。如果你需要更自然的数学表达式流程,可以考虑使用第三方库(如gonum),它们提供了丰富的数学运算功能,但底层仍然基于方法调用。
总之,虽然中缀方法或运算符重载在Go中不可行,但通过结构体和方法,你可以实现类似的功能,同时保持代码的简洁性和可读性。

