变量后面加感叹号,加了个寂寞

我觉得代码之所以不可控,就在于很多时候不加判断,每个地方都充斥着理所当然的假设,变量非空,也只是一个假设

没有加上 | undefined 会更加剧这种假设行为

做过一个开启严格模式的项目,大改10w行代码,微信后台几乎没有undefined报错。
后面由于项目增长到20w 30w行,做严格检查大家意见很大就关闭了,后台undefined错误每次都能占30%-40%。
很多bug都是测试样本大了才能发现,特别是导量3000 5000人进来后。 :upside_down_face:
不过目前还是没有能推动开启严格模式。
纯实战经验,undefined确实是有用的,能很好提高代码健壮性。但是推动需要考虑效率和大家的心态,需要取舍

image TS的严格模式,打开它你会发现一片红色大陆

如果我知道一个变量已经不为空,为什么还要判断一次?

let a: object | undefined;
def initA () {
  a = {};
}
initA();
a!.toString(); // 不报错了

你知道,ts不知道~

各位,这么不喜欢严格模式吗? :joy:
那kotlin这类语言,咋玩

没有加上 | undefined 会更加剧这种假设行为
这句不认同
是否报错取决于变量是否非法,跟你加不加| undefined没任何关系

举个最简单的栗子,你现在调用的任何 cocos 引擎接口,都有可能给你返回 undefined,如果编码时没办法给到你类型提示,那你就只能自己运行时去跑跑看,什么时候踩坑遇到 undefined,引擎不负责。结果就是这样的

这是作为一个工具开发者应该要有的契约精神,我说了这里可能会返回 undefined,就有可能会;如果我说这里一定不会有 undefined,而运行时返回了 undefined,那就是我的工具的问题,不是使用者的问题

ts 的类型提示本身就是一个很好的 api 文档

引用类型初始值赋个null都不行,这严格模式不要也罢, 比强类型语言还难用。

不需要这么麻烦啊,接口返回的任何值,都一律视同可能undefined来处理就行了
如果undefined是非法值,那就排查为什么会出现这种异常,严格模式不能帮你解决这个问题。

也是可以的,我个人不太喜欢这种处理方式,还是太依赖运行时去检查错误了

你说的强类型语言是以前的,新出的,都是这样。
eg(kotlin)

// 声明一个可为空的类型
var a: String? = null
 
// 声明一个非空类型
var b: String = ""
 
// 给非空类型赋空值会报错
// b = null // 错误:不能为非空类型分配null
 
// 正确的做法是使用空字符串或者其他合适的默认值
b = ""
 
// 或者使用`?.`安全调用操作符来安全地赋值
b?.let {
    // 当b不为null时执行代码
}

这啥啊 :upside_down_face:
这不纯纯增加精神内耗么

个人认为,现代语言的趋势是

  1. 胶水化(代码简洁)
  2. 智能化(猜测错误)
    比如java时代
String a = null;
a.length; // 运行时报错
// 正确做法
if (null != a) {
a.length;
}

kotlin时代

val a: String = null; // 报错
val a: String? = null; // 可行
a.b // 报错
a?.b // 可行

你们之所以有疑问,大概率是你们写java等类型代码比较少,一个成熟的java项目,个人感觉代码最多的是xxx != null。而jser,之所以没有这种习惯,是因为大部分情况下报错了也就报错,但是java这种错误极有可能就是闪退中断等。
所以一名合格的javaer,一定是一名合格的判空程序员。
而近几年出现的语言,比如kotlin、ts,将判断用?代替,这个改变,至少对javaer而言,是个巨大的解放

关于另外一个话题,为什么!之后依然报错,因为!只是编译提示,kotlin也是如此。
即可以理解为,当你定义这个变量可以为空,但使用!时,编译器将这个决定权交给你来操作了。之所以有这种操作,个人认为,在实际编程中,一定有开始不想定义,但是这个值使用前一定会赋值的清空,所以有了这个操作。

跟语言没关系,是否需要判空,取决于数据来源。
如果是自己产生的数据,重要的是解决产生非法数据的起源,而不是靠判空来兜底。追求所谓的代码“”“健壮性”,反而不利于及时发现Bug。
如果是别人产生的数据(例如服务器传过来的、用户输入的),那肯定要做非法判断的。
关键是看数据来源是否由自己掌控。

  1. 如果编程离开实际,其实毫无意义,让程序毫无bug,这种情况不存在。所以,对于上线的项目,你觉得根本不需要判断的代码,在每个java项目里都有一堆。
  2. 你说的判空兜底,现在的语言不就是这样的吗?你用?说明可能为空,你用!说明一定不为空,不就是由你来控制的吗?
  3. 你想让编译器加!实现什么逻辑?如果加了但为空的时候不报错,那么这不跟?的性质一样吗?如果加了单为空的时候报错,似乎现在就是这样的

?可能为空会影响运行,所以我一直用
!断言不为空不会影响运行,该报错还是报错,所以我觉得意义不大

参考上面的回复,现代语言是尽可能推测可能的问题,如果你不加,编译器会认为这里可以为空,而你直接操作了对象,因此编译器会提示你~
你总不能说,你知道这里肯定不为空,但是可能为空吧?

喜欢这么搞 大家都去用rust吧 :sweat_smile:

不想加 把strict关了吧