Go语言为什么不支持三元运算符原理解析

 更新时间:2023年08月07日 09:10:38   作者:煎鱼  
这篇文章主要为大家介绍了Go语言为什么不支持三元运算符原理解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

引言

这是一个很多其他语言工程师转 Go 语言的时间节点,这就难免不论一番比较。其中一个经典的运算上的就是 “三元运算符”:

为什么 Go 语言不支持三元运算符,Go 不支持三元运算符就是设计的不好,是历史在开倒车吗?

今天就由煎鱼来和大家一起摸索为什么。

三元运算符是什么

三元运算符,在典型的数学意义上,或者从解析器的角度来看,是一个需要三个参数的运算符。而我们日常中,最常见的是二元运算符:

x + y
x / y
x * y

还有一元运算符:

-a
~b
!c

以及今天的男主角 “三元运算符”。在 C/C++ 等多种语言中,我们可以根据条件声明和初始化变量的习惯来选择性使用三元条件运算符:

int index = val > 0 ? val : -val

Go 使用三元运算符

想在 Go 语言里也使用三元运算符时,发现居然没有...想要实现与上面相同的代码段的方式似乎只能:

var index int
if val > 0 {
    index = val
} else {
    index = -val
}

看上去十分的冗余,不够简洁。

为什么 Go 没有三元运算符

为什么 Go 没有 ?: 操作符,没有的话,官方推荐的方式是怎么样的。

通过 Go FAQ 我们可以得知:

Go 官方就是推荐我们使用前面提到的方式来替代,并且明确了如下态度:

  • Go 中没有 ?: 的原因是语言的设计者看到这个操作经常被用来创建难以理解的复杂表达式。
  • 在替代方案上,if-else 形式虽然较长,但无疑是更清晰的。一门语言只需要一个条件控制流结构。

整体来讲,Go 语言的设计者是为了考虑可读性拒绝了实现三元运算符,"less is more." 也是标榜台词了。

社区争议

Go 语言的一些点与众不同,基本是大家皆知的。无论是 if err != nil,又或是本次的三元运算符,要大家用 if-else 替代:

if expr {
    n = trueVal
} else {
    n = falseVal
}

反对

因此有社区小伙伴给出了反对,基本分为如下几类:

  • 认为 if-else 也有以类似情况能被滥用,设计者的理由不够充分,认为是 “借口”。
  • 认为三元运算符的 “丑陋” 问题,是开发者的编码问题,而不是语言问题。三元在各种语言中很常见,它们是正常的,Go 语言也应该要有。
  • 认为用 if-else 替代三元运算符也很麻烦,让开发者多读了 3-4 行和额外的缩进级别。

同意

认可这个决策的也有不少,为此给出了大量的真实工程案例。

一般来讲,我们用三元运算符是希望这么用:

cond ? true_value : false_value

你可能见过这么用:

cond ? value_a + value_b : value_c * value_d

还见过这样:

(((cond_a ? val_one) : cond_b) ? val_two) : val_three
cond_a ? (val_one : (cond_b ? (val_two : val_three)))

还能嵌套三元运算符:

int a = cond_a ? val_one :
    cond_b ? val_two :
    cond_c ? val_three : val_four;

也能出现可读性更差的:

void rgb_to_lightness_(
  const double re, const double gr, const double bl, double &li)
{
  li=((re < gr) ? ((gr < bl) ? bl : gr) : ((re < bl) ? bl : re) +
                            (gr < re)
                          ? ((bl < gr) ? bl : gr)
                          : ((bl < re) ? bl : re)) / 2.0;
}

说白了就是真实的代码工程中,大家见到过大量三元运算符滥用的场景,纷纷给出了大量的难理解的例子,让大家困扰不堪。

总结

在这篇文章中,首先针对 “三元运算符” 做了基本的介绍。紧接着根据 Go 语言不支持三元的态度进行了说明,且面向社区的争议我们分为了正反方面的基本诠释。

实际上一个简单的 ?: 既整洁又实用,但是没有很好又高效的办法方法可以防止丑陋的嵌套,也就是排除可读性的问题。

在真实的业务工程中,常常能看到一个三元运算符,一开始只是很简单。后面嵌套越加越深,逻辑越写越复杂,从而带来了许多维护上的问题

给大家抛出如下问题:

  • 你认为 Go 语言是否要有三元运算符呢?
  • 如果要有,复杂嵌套的三元运算符又如何考虑呢?

以上问题留给大家思考,更多关于Go 三元运算符的资料请关注脚本之家其它相关文章!

相关文章

  • golang语法使用的注意事项

    golang语法使用的注意事项

    这篇文章主要给大家介绍了关于golang语法使用的一些注意事项,Golang是一种静态类型的编程语言,它支持基本的数据类型,包括整型、浮点型、布尔型、字符串型,需要的朋友可以参考下
    2023-07-07
  • Go语言实现UDP协议及TCP通讯

    Go语言实现UDP协议及TCP通讯

    这篇文章介绍了Go语言实现UDP协议及TCP通讯的方法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-07-07
  • golang map的基本操作及定义方式

    golang map的基本操作及定义方式

    这篇文章主要介绍了golang-map的基本操作,由于map是引用类型,所以在操作的时候,必须先初始化,本文通过多种方式给大家讲解map的定义方式,需要的朋友可以参考下
    2022-08-08
  • Go语言实现单例模式的多种方法

    Go语言实现单例模式的多种方法

    单例模式是一种创建型设计模式,Go中常见实现包括使用sync.Once、双重检查锁定和原子操作法,每种方法都有其独特的优点和适用场景,下面就来具体介绍一下
    2025-07-07
  • Go语言压缩和解压缩tar.gz文件的方法

    Go语言压缩和解压缩tar.gz文件的方法

    这篇文章主要介绍了Go语言压缩和解压缩tar.gz文件的方法,实例分析了使用Go语言压缩文件与解压文件的技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-02-02
  • Go get命令使用socket代理的方法

    Go get命令使用socket代理的方法

    由于某些不可描述的原因,国内使用 go get 命令安装某些包的时候会超时导致失败,比如 net 包、 sys 包、 tools 包等。这篇文章给大家介绍go get 命令使用socket 代理的方法,感兴趣的朋友一起看看吧
    2018-10-10
  • Go语言中的空值(nil)与零值(zerovalue)区别详解

    Go语言中的空值(nil)与零值(zerovalue)区别详解

    在Go语言中,空值(nil)和零值(zero value)是两个不同的概念,它们在语义、使用场景以及实际的编程实践中有着明显的区别,理解这两者的差异对于编写清晰、健壮的Go代码至关重要,需要的朋友可以参考下
    2024-06-06
  • go语言接口之接口值举例详解

    go语言接口之接口值举例详解

    接口是一种抽象类型,是对其他类型行为的概括与抽象,从语法角度来看,接口是一组方法定义的集合,下面这篇文章主要给大家介绍了关于go语言接口之接口值的相关资料,文章通过代码介绍的非常详细,需要的朋友可以参考下
    2024-06-06
  • Golang实现读取excel文件并转换为JSON格式

    Golang实现读取excel文件并转换为JSON格式

    本文介绍了如何使用Golang读取Excel文件并将其转换为JSON格式,通过安装excelize依赖和创建readExcelToJSON方法,可以实现这一功能,如果需要转换数据类型,可以修改相应的代码,需要的朋友可以参考下
    2025-03-03
  • 深度解密 Go 语言中的 sync.Pool

    深度解密 Go 语言中的 sync.Pool

    sync.Pool 是 sync 包下的一个组件,可以作为保存临时取还对象的一个“池子”。这篇文章主要介绍了深度解密 Go 语言中的sync.Pool,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-04-04

最新评论