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 三元运算符的资料请关注脚本之家其它相关文章!

相关文章

  • Go语言超时退出的三种实现方式总结

    Go语言超时退出的三种实现方式总结

    这篇文章主要为大家详细介绍了Go语言中超时退出的三种实现方式,文中的示例代码简洁易懂,对我们深入了解Go语言有一定的帮助,需要的可以了解一下
    2023-06-06
  • Go中recover与panic区别详解

    Go中recover与panic区别详解

    这篇文章主要介绍了Go中recover与panic区别详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-11-11
  • 一文带你掌握Go语言运算符的使用

    一文带你掌握Go语言运算符的使用

    运算符用于在程序运行时执行数学或逻辑运算。Go 语言内置的运算符有:算术运算符、关系运算符、逻辑运算符、位运算符、赋值运算符、其他运算符。本文将带大家详细了解一下这些运算符的使用,感兴趣的可以了解一下
    2022-04-04
  • 详解如何利用Golang泛型提高编码效率

    详解如何利用Golang泛型提高编码效率

    Golang的泛型已经出来有一段时间了,大家应该或多或少对它有所了解。虽然Golang的泛型在功能上确实比较简单,而且确实可能会增加代码的复杂度,过度使用可能还会降低代码可读性。本文就来介绍一下Golang泛型的相关知识吧
    2023-04-04
  • go内存缓存BigCache实现BytesQueue源码解读

    go内存缓存BigCache实现BytesQueue源码解读

    这篇文章主要为大家介绍了go内存缓存BigCache实现BytesQueue源码解读,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-09-09
  • gorm golang 并发连接数据库报错的解决方法

    gorm golang 并发连接数据库报错的解决方法

    今天小编就为大家分享一篇gorm golang 并发连接数据库报错的解决方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-07-07
  • go格式“占位符”输入输出 类似python的input

    go格式“占位符”输入输出 类似python的input

    这篇文章主要介绍了go格式“占位符”, 输入输出,类似python的input,本文给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-04-04
  • 深入理解go sync.Waitgroup的使用

    深入理解go sync.Waitgroup的使用

    WaitGroup在go语言中,用于线程同步,本文主要介绍了深入理解go sync.Waitgroup的使用,具有一定的参考价值,感兴趣的可以了解一下
    2024-01-01
  • Golang仿ps实现获取Linux进程信息

    Golang仿ps实现获取Linux进程信息

    这篇文章主要为大家学习介绍了Golang如何仿ps实现获取Linux进程信息,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起了解一下
    2023-07-07
  • 如何在 Go语言中使用日志包

    如何在 Go语言中使用日志包

    这篇文章主要介绍了如何在 Go语言中使用日志包,日志文件就是一种快速找到这些 bug,更好地了解程序工作状态的方法,下文基于go语言介绍该详细需要的小伙伴可以参考一下
    2022-04-04

最新评论