南通最专业的开锁公司 南通最好的开锁公司 君威遥控器电池 君威专用汽车钥匙电池雷诺科雷傲汽车钥匙遥控器电池更换方法 南通开锁公司电话_南通修锁 换锁芯 开汽车锁 崇川区 港闸区 如皋 如东开锁 南通开锁公司电话 南通金钥匙开锁服务部-专业开修锁 换锁芯(正规公安工商备案) 南通开锁公司电话 南通开锁公司修锁 装锁电话|崇川区开锁|港闸区开锁 led吸顶灯光源 吸顶灯32w 吸顶灯 灯管 吸顶灯 节能灯泡 led吸顶灯灯泡 三头吸顶灯 led吸顶灯灯管 欧普圆形吸顶灯 55w吸顶灯 吸顶灯光源 旅游壶 真空保温 汉方养生壶 美的电热水壶15s08a2 半球牌电饭煲 美的 mg123-d hd2 飞科 三洋洗衣机全自动 新安怡 学饮杯 黑苦荞黄酮软胶囊 苦荞糖安胶囊 五彩凉山苦荞茶 苦荞茶250g 全胚芽黑苦荞茶500 内蒙特产苦荞茶 富贵康苦荞茶 苦荞面包邮 正中苦荞茶包邮 正中苦荞茶 包邮 苦荞香茶西部 苦荞香茶 西部 轩庆苦荞玫瑰鲜花饼 苦荞真空 苦荞500克 苦荞茶120 苦荞 真空 0.02安全套包邮0.2大力马鱼线0.4mm0.4鱼线0.5l氮纤维高压瓶007sh充电器007电子请柬00高达xn-raiser01102400018401背囊0-25微米千分尺03g101系列全套图集0-3个月婴儿连体哈衣05-08本田奥德赛05ffc23套机05版河南动感地带0603贴片电阻包06年款英派斯06斯巴鲁森林人cd机07军衔07军用水壶07款福克斯两厢07数码迷彩07速腾大灯总成 泰好大门锁 泰好豪华大门锁 cei超b级锁芯 玻璃橱门锁 指纹锁耶鲁4109 耶鲁凯特曼指纹锁 防盗挂锁包邮 包挂锁 包梁挂锁 新君威门锁 新君威门锁扣 指纹锁木门 太空铝黑色门锁 泰好浴室铜门锁 浴室门锁不锈钢 1178冷库门锁 南通配新桑塔纳2000 3000 时代超人 志俊汽车钥匙_配帕桑塔纳钥匙遥控器_帕萨特钥匙全丢重配崇川区 南通配宝来汽车钥匙_配宝来遥控器_宝来钥匙全丢如皋 南通配帕萨特汽车钥匙_配帕萨特遥控器_帕萨特钥匙全丢通州 南通配凯越汽车钥匙_配凯越遥控器_凯越钥匙全丢如东

  • 格子衬衣女 长袖 秋
  • t男恤 短袖 韩版包邮
  • 男士职业衬衫
  • 衬衫 女 长袖点点
  • 衬衫 素色 男 宽松 休闲
  • 职场气质衬衫女
  • t恤男短袖加大码不掉色
  • 帅T 小西装
  • 裤子棕色长裤男
  • 衬衣 女 灯芯绒
  • 衬衣 女商务
  • 女士职业衬衫短袖
  • 休闲裤 男 修身
  • jamesearl纯棉休闲长裤
  • 占姆士女式长袖衬衫
  • 男黑色商务休闲棉长裤
  • 女士长袖衬衫
  • 男士绿色休闲长裤
  • 全棉短袖衬衫 男 薄
  • 女士长袖纯棉衬衫
  • 秋裤男直筒
  • 马自达3汽车挂件吊坠饰品 高档琉璃汽车挂饰品蒙迪欧致胜汽车挂件吊坠饰品 高档琉璃汽车挂饰品 启辰D50汽车挂件吊坠饰品 高档琉璃汽车挂饰品起亚K2汽车挂件吊坠饰品 高档琉璃汽车挂饰品索纳塔汽车挂件吊坠饰品 高档琉璃汽车挂饰品天籁汽车挂件吊坠饰品 高档琉璃汽车挂饰品 天语SX4汽车挂件吊坠饰品 高档琉璃汽车挂饰品英朗GT汽车挂件吊坠饰品 高档琉璃汽车挂饰品英伦SC7汽车挂件吊坠饰品 高档琉璃汽车挂饰品自由舰汽车挂件吊坠饰品 高档琉璃汽车挂饰品雨燕汽车挂件吊坠饰品 高档琉璃汽车挂饰品雪佛兰迈锐宝汽车挂件吊坠饰品 高档琉璃汽车挂饰品

    秋冬季现代瑞纳 宝马5系 帕萨特 日产骐达专用汽车毛绒方向盘套 江苏省盐城市地图2014 最新版 江苏省卫星地图2014 最新版 百度地图-谷歌地图-中国地图-北京地图-搜狗地图google地图 广本凌派汽车座垫 凌派秋冬季汽车坐垫 四季通用 长安福特福克斯油耗详解 宝来汽车遥控钥匙电池 更换方法 图解宝来遥控钥匙的电池换法 宝骏630车钥匙遥控器电池更换步骤 更换方法 迈腾车钥匙电池 迈腾更换遥控器电池详解逍客汽车钥匙电池 遥控器逍客智能钥匙的电池更换步骤 新天籁智能遥控钥匙电池 新天籁智能钥匙如何更换纽扣电池 golf6 汽车钥匙遥控器换电池 图解高尔夫6遥控钥匙的电池换法 长安福特福克斯加速时间详解[图] 福克斯汽车钥匙电池 福克斯钥匙电池更换作业 Q5车钥匙更换电池方法 图解新凯越车钥匙更换电池
  • 汽车坐垫 可爱
  • wrc汽车坐垫
  • 汽车坐垫套四季通用
  • 明锐冰丝 汽车坐套
  • 骐达汽车脚垫全包围
  • 三菱蓝瑟汽车坐垫
  • 捷达汽车脚垫 3d
  • 奥迪S7坐垫
  • 别克荣御坐垫
  • Jeep指南者坐垫
  • 力帆320坐垫
  • 路虎卫士坐垫
  • 双龙爱腾坐垫
  • 斯柯达Yeti坐垫
  • 现代途胜坐垫
  • 一汽威乐坐垫
  • 哈飞路宝汽车坐垫
  • 吉利远景汽车坐垫
  • 吉利全球鹰汽车坐垫
  • 房门锁执手锁 防盗挂锁
  • 运动短裤
  • 短裤 男
  • 半裙
  • 手工拖鞋鞋底
  • iphone4皮套 手机套
  • 机油滤清器扳手工具
  • 桑塔纳3000机油
  • 家居摆件现代
  • 玻璃摆件
  • 瓷器摆件
  • 马到成功摆件
  • 高档瓷器摆件
  • 宝马山地自行车包邮
  • 根雕工艺品摆件
  • 家居摆件吊脚娃娃
  • 泰国佛像摆件工艺品
  • 美利达儿童自行车
  • 天鹅摆件结婚
  • 龙龟摆件纯铜
  • 金摆件聚宝盆
  • 亲子自行车 女式
  • 客厅卧室装饰摆件
  • 贵宾狗摆件
  • 木摆件
  • 羚羊头摆件
  • 招财兔摆件
  • 自行车前包
  • 牛仔短裤
  • 短裤 男 休闲
  • 高腰短裤
  • 夏季短裤
  • 蕾丝短裤
  • 连体短裤
  • 裙裤
  • 裤裙
  • 拖鞋 海外
  • 拖鞋 浴室
  • 拖鞋 防滑
  • 拖 鞋 男
  • 拖鞋 女
  • 浴室拖鞋
  • 家居拖鞋
  • 凉拖鞋
  • 夏天拖鞋
  • 香菇丸
  • 韩国饮料
  • 打草绳小松打草绳二手挖掘机小松 小松割灌机配件 钢木书桌办公桌钢木桌玻璃杯子水壶钢化玻璃水壶钢木办公桌钢木电脑桌进口玻璃水壶玻璃水成份防冻玻璃水包邮防冻玻璃水车用 环保果皮箱环保垃圾袋环保垃圾桶小松120-6常州小松割草机小松打草头小松割灌机小松割灌机配件 咖啡厅员工制服_咖啡厅服务员制服_西餐咖啡服务员制服_咖啡馆制服_咖啡店西餐
  • 5号充电电池8节套装
  • 5-7号电池充电器
  • 充电电池5号正品
  • 可充电电池5号
  • 7号充电电池批发
  • 7号电池包邮
  • 1.5v充电电池5号
  • 5号充电器电池免邮
  • 双鹿电池5号正品
  • 双鹿9v电池
  • 双鹿电池批发
  • 双鹿7号电池
  • 双鹿1号电池
  • 双鹿碱性电池
  • 三星s4电池原装正品
  • 三星s4原装电池后盖
  • n7100原装电池
  • 小米2s原装电池
  • galaxy s4大容量电池
  • galaxy s4原装电池
  • galaxy s3电池
  • galaxy nexus电池
  • 三星galaxy s4电池后盖
  • 品胜小米2s电池
  • 品胜手机电池
  • 小米2a电池品胜
  • 背夹电池iphone4s
  • note2背夹电池
  • 三星s4背夹电池皮套
  • 自行车fixedgear 自行车眼镜 近视 婴儿推车小自行车 自行车骑行眼镜风镜 钻石自行车 山地自行车立管 led自行车气嘴专用灯 三鼎自行车坐椅儿童 自行车线管 金镶玉玉器挂件 自行车脚踏双轴承 铬钼钢架自行车 邦德自行车女式 山地公路自行车 自行车骑行手电筒 自行车灯架 灯夹包邮 自行车水壶支架 自行车 组装 mosso 自行车载mp3 26自行车 男生单车 自行车 折叠 复古 giant山地车 自行车 炫彩自行车 七彩马亲子自行车 ucc山地车 自行车 贝嘉琦 女孩自行车 zxc自行车配件码表 自行车前置安全椅 女童自行车 小龙哈比 自行车碳纤维垫圈 自行车骑行用品 装饰木板板材 美式壁挂装饰 家具装饰配件 衣服装饰亮片 婚礼礼品实用 公司开业庆典礼品 婴儿衣柜 儿童欧式公主床 床围栏护栏嵌入式 床靠背套 派克圆珠笔芯 卧室台灯床头灯现代 个性笔袋 派克im签字笔 彩色铅笔包邮 派克宝珠笔芯 派克笔芯正品 百乐摩可擦笔笔芯 斑马油笔 微型钢笔钓鱼竿 电子教鞭遥控笔 镭射灯激光笔 彩色水笔芯 黑色水笔笔芯 公爵宝珠笔芯 touch3代马克笔 韩国文具笔包邮 水溶性彩色铅笔 马可 sgp触控笔 礼品创意笔筒 铂金 项链 pt950 男 老竹笔筒 竹雕笔筒 六福珠宝铂金手镯 8.9寸笔记本电脑 三菱签字笔1.0 华硕游戏笔记本 插座面板

    函数式思维: 利用 Either 和 Option 进行函数式错误处理 类型安全的函数式异常

    当您研究函数式编程等深奥学科时,令人着迷的分支偶尔会出现。在 函数式思维:函数设计模式,第 3 部分 中,我在迷你系列中继续以函数的方式重新思考传统的 Gang of Four 设计模式。在下一期文章中,我将回到这一主题,讨论 Scala 风格的模式匹配,但首先我需要通过 Either 概念建立一些背景知识。Either 的其中一个用法是函数式风格的错误处理,我会在本期文章中对其进行介绍。当您了解 Either 可以对错误施展的魔法之后,我将在下期文章中转向模式匹配和树。

    在 Java 中,错误的处理在传统上由异常以及创建和传播异常的语言支持进行。但是,如果不存在结构化异常处理又如何呢?许多函数式语言不支持异常范式,所以它们必须 找到表达错误条件的替代方式。在本文中,我将演示 Java 中类型安全的错误处理机制,该机制绕过正常的异常传播机制(并通过 Functional Java 框架的一些示例协助说明)。

    函数式错误处理

    如果您想在 Java 中不使用异常来处理错误,最根本的障碍是语言的限制,因为方法只能返回单个值。但是,当然,方法可以 返回单个 Object(或子类)引用,其中可包含多个值。那么,我可以使用一个 Map 来启用多个返回值。请看看清单 1 中的 divide() 方法:


    清单 1. 使用 Map 处理多个返回值
    				 public static Map<String, Object> divide(int x, int y) {     Map<String, Object> result = new HashMap<String, Object>();     if (y == 0)         result.put("exception", new Exception("div by zero"));     else         result.put("answer", (double) x / y);     return result; }   

    清单 1 中,我创建了一个 Map,以 String 为键,并以 Object 为值。在 divide() 方法中,我输出 exception 来表示失败,或者输出 answer 来表示成功。清单 2 中对两种模式都进行了测试:


    清单 2. 使用 Map 测试成功与失败
    				 @Test public void maps_success() {     Map<String, Object> result = RomanNumeralParser.divide(4, 2);     assertEquals(2.0, (Double) result.get("answer"), 0.1); }  @Test public void maps_failure() {     Map<String, Object> result = RomanNumeralParser.divide(4, 0);     assertEquals("div by zero", ((Exception) result.get("exception")).getMessage()); }   

    清单 2 中,maps_success 测试验证在返回的 Map 中是否存在正确的条目。maps_failure 测试检查异常情况。

    这种方法有一些明显的问题。首先,Map 中的结果无论如何都不是类型安全的,它禁用了编译器捕获特定错误的能力。键的枚举可以略微改善这种情况,但效果不大。其次,该方法调用器并不知道方法调用 是否成功,这加重了调用程序的负担,它要检查可能结果的词典。第三,没有什么能阻止这两个键都有值,这使得结果模棱两可。

    我需要的是一种让我能够以类型安全的方式返回两个(或多个)值的机制。

    回页首

    Either

    返回两个不同值的需求经常出现在函数式语言中,用来模拟这种行为的一个常用数据结构是 Either 类。在 Java 中,我可以使用泛型创建一个简单的 Either 类,如清单 3 所示:


    清单 3. 通过 Either 类返回两个(类型安全的)值
    				 public class Either<A,B> {     private A left = null;     private B right = null;      private Either(A a,B b) {         left = a;         right = b;     }      public static <A,B> Either<A,B> left(A a) {         return new Either<A,B>(a,null);     }      public A left() {         return left;     }      public boolean isLeft() {         return left != null;     }      public boolean isRight() {         return right != null;     }      public B right() {         return right;     }      public static <A,B> Either<A,B> right(B b) {         return new Either<A,B>(null,b);     }     public void fold(F<A> leftOption, F<B> rightOption) {         if(right == null)             leftOption.f(left);         else             rightOption.f(right);     } } 

    清单 3中,Either 旨在保存一个 leftright 值(但从来都不会同时保存这两个值)。该数据结构被称为不相交并集。一些基于 C 的语言包含 union 数据类型,它可以保存含若干种不同类型的一个实例。不相交并集的槽可以保存两种类型,但只保存其中一种类型的一个实例。Either 类有一个 private 构造函数,使构造成为静态方法 left(A a)right(B b) 的责任。在类中的其他方法是辅助程序,负责检索和调研类的成员。

    利用 Either,我可以编写代码来返回异常 一个合法结果(但从来都不会同时返回两种结果),同时保持类型安全。常见的函数式约定是 Either 类的 left 包含异常(如有),而 right 包含结果。

    解析罗马数字

    我有一个名为 RomanNumeral 的类(我将其实现​​留给读者去想象)和一个名为 RomanNumeralParser 的类,该类调用 RomanNumeral 类。parseNumber() 方法和说明性测试如清单 4 所示:


    清单 4. 解析罗马数字
    				 public static Either<Exception, Integer> parseNumber(String s) {     if (! s.matches("[IVXLXCDM]+"))         return Either.left(new Exception("Invalid Roman numeral"));     else         return Either.right(new RomanNumeral(s).toInt()); }  @Test public void parsing_success() {     Either<Exception, Integer> result = RomanNumeralParser.parseNumber("XLII");     assertEquals(Integer.valueOf(42), result.right()); }  @Test public void parsing_failure() {     Either<Exception, Integer> result = RomanNumeralParser.parseNumber("FOO");     assertEquals(INVALID_ROMAN_NUMERAL, result.left().getMessage()); }   

    清单 4 中,parseNumber() 方法执行一个验证(用于显示错误),将错误条件放置在 Eitherleft 中,或将结果放在它的 right中。单元测试中显示了这两种情况。

    比起到处传递 Map,这是一个很大的改进。我保持类型安全(请注意,我可以按自己喜欢使异常尽量具体);在通过泛型的方法声明中,错误是明显的;返回的结果带有一个额外的间接级别,可以解压 Either 的结果(是异常还是答案)。额外的间接级别支持惰性

    惰性解析和 Functional Java

    Either 类出现在许多函数式算法中,并且在函数式世界中如此之常见,以致 Functional Java 框架(参阅 参考资料)也包含了一个 Either 实现,该实现将在 清单 3清单 4 的示例中使用。但它的目的就是与其他 Functional Java 构造配合使用。因此,我可以结合使用 Either 和 Functional Java 的 P1 类来创建惰性 错误评估。惰性表达式是一个按需执行的表达式(参阅 参考资料)。

    在 Functional Java 中,P1 类是一个简单的包装器,包括名为 _1() 的方法,该方法不带任何参数。(其他变体:P2P3 等,包含多种方法。)P1 在 Functional Java 中用于传递一个代码块,而不执行它,使您能够在自己选择的上下文中执行代码。

    在 Java 中,只要您 throw 一个异常,异常就会被实例化。通过返回一个惰性评估的方法,我可以将异常创建推迟到以后。请看看清单 5 中的示例及相关测试:


    清单 5. 使用 Functional Java 创建一个惰性解析器
    				 public static P1<Either<Exception, Integer>> parseNumberLazy(final String s) {     if (! s.matches("[IVXLXCDM]+"))         return new P1<Either<Exception, Integer>>() {             public Either<Exception, Integer> _1() {                 return Either.left(new Exception("Invalid Roman numeral"));             }         };     else         return new P1<Either<Exception, Integer>>() {             public Either<Exception, Integer> _1() {                 return Either.right(new RomanNumeral(s).toInt());             }         }; }  @Test public void parse_lazy() {     P1<Either<Exception, Integer>> result = FjRomanNumeralParser.parseNumberLazy("XLII");     assertEquals((long) 42, (long) result._1().right().value()); }  @Test public void parse_lazy_exception() {     P1<Either<Exception, Integer>> result = FjRomanNumeralParser.parseNumberLazy("FOO");     assertTrue(result._1().isLeft());     assertEquals(INVALID_ROMAN_NUMERAL, result._1().left().value().getMessage()); }   

    清单 5 中的代码与 清单 4 中的类似,但多了一个 P1 包装器。在 parse_lazy 测试中,我必须通过在结果上调用 _1() 来解压结果,该方法返回 Eitherright,从该返回值中,我可以检索值。在 parse_lazy_exception 测试中,我可以检查是否存在一个 left,并且我可以解压异常,以辨别它的消息。

    在您调用 _1() 解压 Eitherleft 之前,异常(连同其生成成本昂贵的堆栈跟踪)不会被创建。因此,异常是惰性的,让您推迟异常的构造程序的执行。

    提供默认值

    惰性不是使用 Either 进行错误处理的惟一好处。另一个好处是,您可以提供默认值。请看清单 6 中的代码:


    清单 6. 提供合理的默认返回值
    				 public static Either<Exception, Integer> parseNumberDefaults(final String s) {     if (! s.matches("[IVXLXCDM]+"))         return Either.left(new Exception("Invalid Roman numeral"));     else {         int number = new RomanNumeral(s).toInt();         return Either.right(new RomanNumeral(number >= MAX ? MAX : number).toInt());     } }  @Test public void parse_defaults_normal() {     Either<Exception, Integer> result = FjRomanNumeralParser.parseNumberDefaults("XLII");     assertEquals((long) 42, (long) result.right().value()); }  @Test public void parse_defaults_triggered() {     Either<Exception, Integer> result = FjRomanNumeralParser.parseNumberDefaults("MM");     assertEquals((long) 1000, (long) result.right().value()); }   

    清单 6 中,假设我不接受任何大于 MAX 的罗马数字,任何企图大于该值的数字都将被默认设置为 MAXparseNumberDefaults() 方法确保默认值被放置在 Eitherright 中。

    包装异常

    我也可以使用 Either 来包装异常,将结构化异常处理转换成函数式,如清单 7 所示:


    清单 7. 捕获其他人的异常
    				 public static Either<Exception, Integer> divide(int x, int y) {     try {         return Either.right(x / y);     } catch (Exception e) {         return Either.left(e);     } }  @Test public void catching_other_people_exceptions() {     Either<Exception, Integer> result = FjRomanNumeralParser.divide(4, 2);     assertEquals((long) 2, (long) result.right().value());     Either<Exception, Integer> failure = FjRomanNumeralParser.divide(4, 0);     assertEquals("/ by zero", failure.left().value().getMessage()); }   

    清单 7 中,我尝试除法,这可能引发一个 ArithmeticException。如果发生异常,我将它包装在 Eitherleft 中;否则我在 right 中返回结果。使用 Either 使您可以将传统的异常(包括检查的异常)转换成更偏向于函数式的风格。

    当然,您也可以惰性包装从被调用的方法抛出的异常,如清单 8 所示:


    清单 8. 惰性捕获异常
    				 public static P1<Either<Exception, Integer>> divideLazily(final int x, final int y) {     return new P1<Either<Exception, Integer>>() {         public Either<Exception, Integer> _1() {             try {                 return Either.right(x / y);             } catch (Exception e) {                 return Either.left(e);             }         }     }; }  @Test public void lazily_catching_other_people_exceptions() {     P1<Either<Exception, Integer>> result = FjRomanNumeralParser.divideLazily(4, 2);     assertEquals((long) 2, (long) result._1().right().value());     P1<Either<Exception, Integer>> failure = FjRomanNumeralParser.divideLazily(4, 0);     assertEquals("/ by zero", failure._1().left().value().getMessage()); }   

    嵌套异常

    Java 异常有一个不错的特性,它能够将若干种不同的潜在异常类型声明为方法签名的一部分。尽管语法越来越复杂,但 Either 也可以做到这一点。例如,如果我需要 RomanNumeralParser 上的一个方法允许我对两个罗马数字执行除法,但我需要返回两种不同的可能异常情况,那么是解析错误还是除法错误?使用标准的 Java 泛型,我可以嵌套异常,如清单 9 所示:


    清单 9. 嵌套异常
    				 public static Either<NumberFormatException, Either<ArithmeticException, Double>>          divideRoman(final String x, final String y) {     Either<Exception, Integer> possibleX = parseNumber(x);     Either<Exception, Integer> possibleY = parseNumber(y);     if (possibleX.isLeft() || possibleY.isLeft())         return Either.left(new NumberFormatException("invalid parameter"));     int intY = possibleY.right().value().intValue();     Either<ArithmeticException, Double> errorForY =              Either.left(new ArithmeticException("div by 1"));     if (intY == 1)         return Either.right((fj.data.Either<ArithmeticException, Double>) errorForY);     int intX = possibleX.right().value().intValue();     Either<ArithmeticException, Double> result =              Either.right(new Double((double) intX) / intY);     return Either.right(result); }  @Test public void test_divide_romans_success() {     fj.data.Either<NumberFormatException, Either<ArithmeticException, Double>> result =          FjRomanNumeralParser.divideRoman("IV", "II");     assertEquals(2.0,result.right().value().right().value().doubleValue(), 0.1); }  @Test  public void test_divide_romans_number_format_error() {     Either<NumberFormatException, Either<ArithmeticException, Double>> result =          FjRomanNumeralParser.divideRoman("IVooo", "II");     assertEquals("invalid parameter", result.left().value().getMessage()); }  @Test public void test_divide_romans_arthmetic_exception() {     Either<NumberFormatException, Either<ArithmeticException, Double>> result =          FjRomanNumeralParser.divideRoman("IV", "I");     assertEquals("div by 1", result.right().value().left().value().getMessage()); }   

    清单 9 中,divideRoman() 方法首先解压从 清单 4 的原始 parseNumber() 方法返回的 Either。如果在这两次数字转换的任一次中发生一个异常,Either left 与异常一同返回。接下来,我必须解压实际的整数值,然后执行其他验证标准。罗马数字没有零的概念,所以我制定了一个规则,不允许除数为 1:如果分母是 1,我打包我的异常,并放置在 rightleft 中。

    换句话说,我有三个槽,按类型划分:NumberFormatExceptionArithmeticExceptionDouble。第一个 Eitherleft 保存潜在的 NumberFormatException,它的 right 保存另一个 Either。第二个 Eitherleft 包含一个潜在的 ArithmeticException,它的 right 包含有效载荷,即结果。因此,为了得到实际的答案,我必须遍历 result.right().value().right().value().doubleValue()!显然,这种方法的实用性迅速瓦解,但它确实提供了一个类型安全的方式,将异常嵌套为类签名的一部分。

    回页首

    Option

    Either 是一个方便的概念,在下期文章中,我将使用这个概念构建树形数据结构。Scala 中有一个名为 Option 的类与之类似,该类在 Functional Java 中被复制,提供了一个更简单的异常情况:none 表示不合法的值,some 表示成功返回。Option 如清单 10 所示:


    清单 10. 使用 Option
    				 public static Option<Double> divide(double x, double y) {     if (y == 0)         return Option.none();     return Option.some(x / y); }  @Test public void option_test_success() {     Option result = FjRomanNumeralParser.divide(4.0, 2);     assertEquals(2.0, (Double) result.some(), 0.1); }  @Test public void option_test_failure() {     Option result = FjRomanNumeralParser.divide(4.0, 0);     assertEquals(Option.none(), result);  }   

    清单 10 所示,Option 包含 none()some(),类似于 Either 中的 leftright,但特定于可能没有合法返回值的方法。

    Functional Java 中的 EitherOption 都是单体,表示计算 的特殊数据结构,在函数式语言中大量使用。在下一期中,我将探讨有关 Either 的单体概念,并在不同的示例中演示它如何支持 Scala 风格的模式匹配。

    回页首

    结束语

    当您学习一种新范式时,您需要重新考虑所有熟悉的问题解决方式。函数式编程使用不同的习惯用语来报告错误条件,其中大部分可以在 Java 中复制,不可否认,也有一些令人费解的语法。

    在下一期中,我将深入探讨单体,讨论这个迷人的概念的一些用法,并展示如何使用低级的 Either 构建树。

    posted @ 2012-07-16 20:57  ChaunceyHao  阅读(243)  评论(0编辑  收藏  举报
  • 汽车羊毛坐垫长毛
  • 车垫四季通用
  • 御车宝
  • 凯美瑞坐垫四季通用
  • 手编冰丝坐垫
  • 珍珠戒指新款
  • 汽车皮坐垫四季垫
  • 汽车四季坐垫新款
  • 汽车皮坐垫四季通用
  • 汽车羊毛坐垫短毛
  • 包女
  • 汽车亚麻坐垫包邮
  • 汽车布坐垫
  • 汽车布坐垫套
  • 紫风铃亚麻四季坐垫
  • 蒙奇奇汽车
  • 蒙奇奇汽车毛绒坐垫
  • 蒙奇奇坐垫三件套
  • 尼罗河车坐垫
  • 尼罗河手编坐垫
  • 尼罗河四季垫
  • 羊剪绒坐垫
  • 牧宝冬季坐垫
  • 牧宝四季垫正品
  • 牧宝羽绒坐垫
  • 牧宝汽车垫羊毛
  • 高压洗车机
  • 高压洗车器
  • 高压洗车水泵
  • 高压洗车泵
  • 熊猫洗车
  • 洗车器高压220v
  • 洗车器便携高压
  • 高压水枪洗车机
  • 220v高压水枪洗车机
  • 家用洗车水枪高压枪
  • 汽车洗车水枪
  • 虎贝尔洗车水枪
  • 水枪头洗车
  • 洗车水枪水管
  • 洗车水枪套装
  • 洗车水枪接头
  • 佳百丽洗车水枪
  • 洗车工具套装
  • 洗车用品工具
  • 家用洗车工具
  • 汽车洗车工具
  • 洗车设备工具
  • 洗车刷子
  • 现代途胜保险杠
  • 现代新胜达保险杠
  • 保险杠车贴纸
  • 后保险杠车贴纸
  • 前保险杠车贴
  • 雨燕保险杠
  • 后保险杠贴纸
  • 前保险杠贴纸
  • 汽车保险贴纸
  • rav4后保险杠
  • 专业运动文胸htc c715e evo design 4g
  • htc evo 4g a9292
  • htc x515m g17 evo 3d
  • htc one x s720e
  • htc x920e
  • 名牌手表男正品
  • povos 奔腾 pffn3003苏泊尔电热水壶正品
  • tcl tcl电热水壶ta-kb181a
  • 乔邦181j
  • 乔邦不锈钢电热水壶
  • supor 苏泊尔 swf15j3-150
  • 逸动空气滤芯
  • 空气压缩机喷漆
  • 德国车载空气净化器
  • sr927w手表电池
  • cartier手表蓝气球
  • 机械手表男士名表
  • anne klein手表
  • 手表柜台展示柜
  • 女士皮带 头层牛皮
  • 女士皮带 头层纯牛皮
  • jeep皮带 纯牛皮
  • 女皮带 真皮 牛皮
  • 女士皮带 真皮
  • 头层牛皮皮带
  • 女士皮带 时尚
  • 真皮皮带头层牛皮女
  • 女士皮带 包邮
  • 皮带条 头层牛皮
  • 女士皮带 时尚 宽
  • 头层牛皮纯铜扣皮带
  • 女士皮带 纯牛皮
  • 女士皮带头层纯牛皮
  • 女士皮带头层牛皮
  • jeep皮带纯牛皮
  • 女皮带真皮牛皮
  • 女士皮带真皮
  • 女士牛皮皮带包邮
  • 女士皮带时尚
  • 三星微单镜头
  • 三星单反镜头
  • 三星50-200镜头
  • 三星7100镜头保护膜
  • 三星i9210
  • 三星i9210手机套面包蛋糕酸奶机
  • 鸡蛋牛奶面包干饼干
  • 面包片饼干
  • 摩托车机油