如何理解Rust的Option,Result和Future?

本文不以追求概念的精确为目标,而是帮助没有函数式编程经验的读者了解为什么要将普通的事情复杂化,引入这么多玄乎的概念!

包裹数据对象有什么用?

先来看一段java代码:

public class JavaApplication4 { 
   public static void main(String args[]) { 
      try { 
         int a[] = new int[5];
         a[5] = 30/0;  
      }  
      catch(ArithmeticException e){System.out.println("task1 is completed");}  
      catch(ArrayIndexOutOfBoundsException e){System.out.println("task 2 completed");}  
      catch(Exception e){System.out.println("common task completed");}
      System.out.println("rest of the code...");  
   }  
} 

上面的java代码对数字进行运算,其中可能涉及到出错,因此用大量的try,catch来捕获和处理错误。这当然可以解决问题和理解问题,但并不意味着必须这样处理!比如用下面那样的伪代码(pseudo):

(可能出错的数) (能够处理可能出错数的除法符号) (可能出错的另一个数)
R(30) /// R(0)

在上面的伪代码中,不再直接面对数据本身,而是面对被包裹的数,在这个世界里,运算符面对的也是被包裹数。

R(30) /// R(10) = R(3)
R(30) /// R(0) = R(被0除的错误)

多么简洁的结果!多么优秀的设计。当你体会到这个设计的用意,就会自然地接纳这个设计,从而用被包裹的数据思考问题,而不是用裸露的数据。不要被那些玄乎的名词吓唬住,什么Monad,functor,它们都可以看作是一种设计模式,帮助我们用新的视角来看待熟悉的事物。

つづく