好代码,坏代码主要观点

计算机与互联网 [英] 汤姆·朗
简介: 本书分享的实用技巧可以帮助你编写可靠且易于团队成员理解和适应不断变化需求的代码。

附录A

巧克力糕饼食谱

巧克力糕饼食谱

你需要如下原料:

100g黄油

185g 70%黑巧克力

2枚鸡蛋

半茶匙香草香精

185g精白砂糖

50g面粉

35g可可粉

半茶匙盐

70g巧克力屑

制作方法

(1)将烤箱预热到160℃(320℉)。

(2)在15cm×15cm的小烤盘上涂上油并铺上烘焙纸。

(3)将黄油和黑巧克力放在碗里,在装有热水的平底锅上融化。一旦融化,从热源上移开以使其冷却。

(4)在一个碗里打入鸡蛋,放进砂糖和香草香精并搅匀。

(5)在蛋液中加入融化的黄油和黑巧克力并搅匀。

(6)在另一个碗里混合面粉、可可粉和盐,然后筛入鸡蛋、砂糖、黄油和巧克力,充分搅拌使其完全混合。

(7)加入巧克力屑并搅匀,使其混合。

(8)将上述混合物放入烤盘并烘焙20min。

冷却数小时。

附录B

空值安全与可选类型

B.1

使用空值安全

如果我们使用的语言支持空值安全(且我们已按要求启用这一特性),就会有一种注释机制,表示各种类型可取空值。这往往包括表示可为空值的?字符。代码一般像下面这样。

Element? getFifthElement(List<Element> elements) { ←--- Element?中的“?”表示返回类型可以为空值

if (elements.size() < 5) { return null; } return elements[4];}

如果使用这段代码的工程师忘记处理getFifthElement()返回空值的情况,他们的代码将不能编译,如以下代码所示。

void displayElement(Element element) { ... } ←--- 这个函数的参数不可为空(因为类型是Element而非Element?)

void displayFifthElement(List<Element> elements) { Element? fifthElement = getFifthElement(elements); ←--- fifthElement变量可为空,因为它的类型是Element? displayElement(fifthElement); ←--- 这一行将出现编译器错误,因为函数期待一个不可为空的参数,但这里却以可为空的值调用}

为了编译这段代码,工程师必须检查getFifthElement()返回值是否为空,然后才能用它调用参数不可为空的函数。编译器能够推导出哪些代码路径只在该值非空时才能抵达,从而确定该值的使用是否安全。

void displayFifthElement(List<Element> elements) {

Element? fifthElement = getFifthElement(elements); if (fifthElement == null) { displayMessage("Fifth element doesn't exist");

return; ←--- 这条if语句意味着该函数将在fifthElement为空时提前返回 } displayElement(fifthElement); ←--- 编译器可推导出这一行只在fifthElement不为空时可达}

注意:编译器警告与编译器错误的对比

在C#中,以不安全的方式使用可为空的值只会造成编译器警告,而不是编译器错误。如果你使用C#并启用空值安全,那么配置你的项目,将这些警告升级为错误以确保它们不会被忽视,可能是明智的做法。

可以看到,有了空值安全机制,我们可以使用空值,并且编译器将跟踪一个值何时在逻辑上可为空、何时不可为空,并确保不会以不安全的方式使用空值。这样,我们就能从空值的实用性上得益,又不会遭遇空指针异常(以及类似问题)的危险。

具有空值安全机制的语言往往提供简洁的语法,以检查某个值是否为空,并只在值不为空时访问其上的成员函数或属性。这可以消除许多重复代码,但本书的伪代码惯例将坚持更详尽的空值检查形式,使其与更广泛的不提供这类语法的语言类似。

版权:人民邮电出版社