三元运算符广泛存在于其他语言中,比如:

python:

val = trueValue if expr else falseValue

javascript:

const val = expr "htmlcode">
const char *val = expr "trueValue" : "falseValue";

然而,被广泛支持的三目运算符在golang中却是不存在的!如果我们写出类似下面的代码:

val := expr "trueValue" : "falseValue"

那么编译器就该抱怨了:invalid character U+003F '"htmlcode">

const status = (type===1"htmlcode">
let status = ''
if (type === 1) {
  if (again === 1) {
    status = '再售'
  } else {
    status = '已售'
  }
} else {
  status = '未售'
}

let word = ''
if (res.distance === 0) {
  word = 'a'
} else {
  if (res.distance === 1 && res.difference > 3) {
    word = 'b'
  } else {
    if (res.distance === 2 && res.difference > 5 && String(res.key).length > 5) {
      word = 'c'
    } else {
      word = 'd'
    }
  }
}

看起来并没有多少的改善,特别是例2,三层嵌套,不管是谁review到这段代码难免不会抱怨你几句。

然而事实上这些代码是可以简化的,考虑到三元运算符总是会给变量一个值,因此最后的else其实可以看作是变量的默认值,于是代码可以这么写:

let status = '未售'
if (type === 1) {
  if (again === 1) {
    status = '再售'
  } else {
    status = '已售'
  }
}

let word = 'd'
if (res.distance === 0) {
  word = 'a'
} else {
  if (res.distance === 1 && res.difference > 3) {
    word = 'b'
  } else {
    if (res.distance === 2 && res.difference > 5 && String(res.key).length > 5) {
      word = 'c'
    }
  }
}

其次,对于例2,显然可以使用else if来清除嵌套结构:

let word = 'd'
if (res.distance === 0) {
  word = 'a'
} else if (res.distance === 1 && res.difference > 3) {
  word = 'b'
} else if (res.distance === 2 && res.difference > 5 && String(res.key).length > 5) {
  word = 'c'
}

现在再来看,显然使用if语句的版本的可读性更高,逻辑也更清晰(通过去除嵌套)。

然而事实也不尽然。除了用三元运算符表达流程控制之外,事实上更常见更广泛的一个应用是如下这样的表达式:

const val = expr "htmlcode">
func If(cond bool, a, b interface{}) {
  if cond {
    return a
  }

  return b
}

age := 20
val := If(age > 18, "成年人", "未成年人").(string)

不推荐这么做是有几个原因:

  1. 使用接口导致性能下降
  2. 需要强制的类型断言
  3. 不管三元表达式还是if语句,对于不会到达的分支是不会计算的,也就是惰性计算;而给函数传递参数时每一个表达式都会被计算

最后总结一下:

三元运算符的优点:

  • 对于简短的表达式使用三元运算符表意更清晰,特别是在习惯了线性阅读三元运算符表达式之后
  • 不需要中间状态(例如第一个例子中的let变量可以替换为const,代码更健壮),心智负担更低
  • 没有中间状态也就意味着更少或完全没有副作用,代码更易跟踪和维护

但三元运算符也有明显的缺点:

  • 对于复杂逻辑代码可读性较差(例如第一个例子中的status,需要在trueValue的位置进行进一步的条件判断时)
  • 容易被滥用,很多人将其用于替代if语句或是简化复杂的if嵌套,这会导致上一条中所描述的结果
  • 条件分支只能为表达式,不支持多条语句

所以这是一个见仁见智的问题,总之只能入乡随俗了。

参考

https://juejin.im/post/6844903561759850510

https://www.it-swarm.dev/zh/javascript/替代js中的嵌套三元运算符/1055944752/

https://golang.org/doc/faq#Does_Go_have_a_ternary_form

总结

标签:
golang,三元运算符,go三元运算符

免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件! 如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
内蒙古资源网 Copyright www.nmgbbs.com

评论“golang中为什么不存在三元运算符详解”

暂无“golang中为什么不存在三元运算符详解”评论...

《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线

暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。

艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。

《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。