Golang中的三元运算符用法解析

Golang中的三元运算符用法解析 我知道在Go语言中不像其他语言(如C/C++/JavaScript/Ruby…)那样有三元运算符。

image

但我发现了这段试图实现相同操作的代码 playground

package main

import "fmt"

func main() {
	a, b := 2, 3
	c := (map[bool]int{true: a, false: a - 1})[a > b]
	fmt.Println(c)
}

这段代码看起来给出了所需的结果,并且等价于:

c = a>b ? a : a-1

但我不理解它。

谁能给我解释一下 (map[bool]int{})[condition]


更多关于Golang中的三元运算符用法解析的实战教程也可以访问 https://www.itying.com/category-94-b0.html

5 回复

你说“变得”难以阅读是什么意思?原帖发布的那堆东西已经难以阅读,充其量也难以理解。除非目的是混淆代码,否则想出那种糟糕代码的人已经失败了。

更多关于Golang中的三元运算符用法解析的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


嗯,这确实是一种技巧。然而,这并不符合 Go 语言的惯用法,并且绝对不推荐使用这样的结构,因为你的代码会变得难以阅读。请改用 if/else 语句,这样生成的代码已经足够优化了。

我采用了相同的代码,但将其拆分为更简单的语句:Go Playground - The Go 编程语言

truefalsebool 类型的值。你可以将它们用作键类型为 bool 的映射中的键。a < b 是一个解析为布尔值的表达式,就像 a - b 解析为整数值一样。因为 a < b 解析为 bool 值,所以你可以将其用作 map[bool]int 的键。

编辑:我的示例没有做完全相同的事情。我想我现在弄对了!

顺便说一下,这段代码并没有完全复制三元运算符的行为(至少与它在大多数语言中的求值方式不同)。

<谓词> ? <结果> : <备选>

在大多数语言中,如果 谓词 是一个求值为 true 的表达式,那么只有 <结果> 会被求值;如果 <谓词> 被设为 false,那么只有 <备选> 表达式会被求值。

打开你的 JS 控制台并输入:

false ? console.log("never printed") : console.log("LOGGED!")

你会在控制台看到 LOGGED。在上面提到的 main 函数中,无论 a > b 的结果如何,aa-1 都会被求值。

这段代码实现了一种类似三元运算符的功能,通过map的键值查找来模拟条件选择。让我详细解释一下:

package main

import "fmt"

func main() {
    a, b := 2, 3
    
    // 原始代码分解:
    // 1. 创建一个map[bool]int
    condition := a > b  // false,因为2 > 3为假
    
    // 2. 创建map字面量
    m := map[bool]int{
        true:  a,      // 如果条件为true,返回a
        false: a - 1,  // 如果条件为false,返回a-1
    }
    
    // 3. 通过条件作为key来获取值
    c := m[condition]  // m[false] = a-1 = 1
    
    fmt.Println(c)  // 输出: 1
}

更清晰的实现方式:

// 方法1:使用map(如原代码)
func ternaryMap(condition bool, trueVal, falseVal int) int {
    return map[bool]int{true: trueVal, false: falseVal}[condition]
}

// 方法2:使用函数(更推荐)
func ternaryFunc(condition bool, trueVal, falseVal int) int {
    if condition {
        return trueVal
    }
    return falseVal
}

// 方法3:使用闭包
func ternaryClosure(condition bool, trueVal, falseVal int) int {
    return func() int {
        if condition {
            return trueVal
        }
        return falseVal
    }()
}

func main() {
    a, b := 2, 3
    
    // 使用map方式
    result1 := ternaryMap(a > b, a, a-1)
    fmt.Println("Map方式:", result1)  // 输出: 1
    
    // 使用函数方式
    result2 := ternaryFunc(a > b, a, a-1)
    fmt.Println("函数方式:", result2)  // 输出: 1
    
    // 使用闭包方式
    result3 := ternaryClosure(a > b, a, a-1)
    fmt.Println("闭包方式:", result3)  // 输出: 1
    
    // 直接使用if语句(Go语言最常用的方式)
    var result4 int
    if a > b {
        result4 = a
    } else {
        result4 = a - 1
    }
    fmt.Println("if语句:", result4)  // 输出: 1
}

这种map方式的原理:

  1. map[bool]int{} 创建了一个键类型为bool,值类型为int的map
  2. {true: a, false: a-1} 初始化map,true对应a,false对应a-1
  3. [a > b] 使用条件表达式的结果(true或false)作为key来查找对应的值
  4. 整个表达式返回找到的值,实现了类似三元运算符的功能

需要注意的是,虽然这种写法很巧妙,但在实际Go代码中,通常更推荐使用明确的if-else语句,因为这样代码更清晰易读。Go语言设计者故意没有包含三元运算符,就是为了保持代码的简洁性和可读性。

回到顶部