新手问题 代码里判断空值的逻辑如何简化?

jiyinyiyong · 2013年08月10日 · 最后由 jiyinyiyong 回复于 2013年08月13日 · 9230 次阅读

nil null undefined 这样的数据比较容易混在数据当中, 比如文件操作,界面数据读取,数据库 (不清晰..), 都可能返回空值, 遇到空值,现在只知道用 if/else 手动判断,对数据做兼容.. 这样写多了发现代码好丑,编辑起来都不顺的, 有没有好的方案来减轻空值对代码逻辑造成的影响呢?

伪代码的例子比如:

data = {}
data.title = $('#panel-x .title').val()
data.content = $('#panel-x .content').val()
data.date = $('#panel-x .date').val()
data.point = $('#panel-x .point').val()

data2 = aFunction(data)
day = data2.day
clock = data2.clock

# save that on server

server.save data2

data3 = server.fetch()

界面上取得的时间 date, 权重 point 都不能以空字符串存储, 于是从服务器和界面取数据,分析转化格式去存储,就有空值的问题,

不妨贴一段比较乱的代码过来看看怎么改比较好

如果是处理字符串,可以 to_s,数字可以 to_i to_f 先。Rails present? presence 可以方便判断各种空值

赋初始值呢?? 比如 a || = ""

ruby 没有 null 吧??

ruby 只有一个 nil 很简单,有的情况 a.b.c.d rescue nil 就行了。rails 还提供了 a.try(:b).try(:c).try(:d) 来方便链式调用。赋初始值的情况可以用 ||= .

如果 lz 说的是 js, 在 js 里 null, undefined 不是对象,没什么可以改进的办法... undefined 可以是变量名比较蛋疼,没有 ||= 也很郁闷... 不过用 coffee 可以添加一些改进。

对于这种 null 问题,正常语言都有一些手段去减少 if else boiler plate 的...

Groovy 有 elvis 运算符 (样子像猫王...) a?.b?.c?.d (coffeescript 里也可以这么用哦) Lisp 里 nil 就是空链表,空字符串也是 nil, 要判断的情况其实要少很多 Haskell 有 Maybe monad, 然后用 do-notation 就不用写一堆 if else 了

foo x = do
  x <- b x
  x <- c x
  x <- d x
  return x
foo (Just a) -- Nothing or Just d

Scala 有仿 Maybe monad 的 Option, 可以用 for {...} 语法去做

for {
  x <- b(x)
  x <- c(x)
  x <- d(x)
} yield x

#4 楼 @luikore javascript 中这个可以不可以?a = a || 1,我在书上看到的,不知道对不对。。。

a.b.c.d rescue nil 这个很神奇,学到了!

#6 楼 @yfractal 如果 a 未定义,a = a || 1 在各浏览器表现不一样,有的会出错有的不会... var a = a || 1 就正常一点

#7 楼 @luikore 哦,谢谢! 刚开看 javascript,感觉这个语言有点不舒服。。。:-)。

#1 楼 @fleuria 补了一个伪代码的例子.. 重点大概是数据在界面和数据库里格式不一致,中间有转化步骤, 转化步骤又需要考虑值是空的,需要手动判断

#5 楼 @luikore 也有好奇过 Haskell 怎么有古怪的 Nothing 的.. 这是数据类型层面就对空值进行处理的么,如果换 coffeerb 有类似方案不?

#11 楼 @jiyinyiyong

就你这个样例来说,用 angular (缺点是不能和 jq 一起用) 或者 rivets (比 angular 轻很多,可以和 jq 一起用) 把 UI 数据绑定到 data object, 就可以少做很多判断了

data.point 和 data.date 不能用空值,属于客户端 validation 的范畴,html5 加了不少校验属性, 可以用 jquery.h5validate 配合 required / pattern / maxlength / min / max 属性去搞。代码中几乎不用判断才对...

反正最后服务器端还得判断一次的,rails 就是 model 里加一行 validate presence 或者 length, 也不用 if ... else 判断的

#11 楼 @jiyinyiyong 嗯,haskell 这个命名 sense 值得吐槽...

#12 楼 @luikore 我碰到的场景不是直接传到服务器的,值也可以是空, 前端代码逻辑偏多,现在还没有用上 Angular, 所以同个模式频繁出现

JS 看起来是落后啊,先进的 Monad, yeild 全不能用.. 我学着结果晕了好久

只是初始值的话,coffee 里面 ?= 的印象不错倒是...

链式调用的话,没有 ruby 内建的 try 或者 haskell 那种 maybe monad,又不想一堆 if..else 或者&&,就只能用 Null Object 模式来 work around 了... 返回 nil 的函数之所以讨厌是因为它有传染性,在日常的函数与方法里总是让它们返回相同的类型可以让生活好过一点?

#15 楼 @fleuria 暂时只能看着 null 手动判断了,以后看看有啥解法

需要 登录 后方可回复, 如果你还没有账号请 注册新账号