隐式转换:比动态类型更强大?

  本文内容主要来自[url=http://www.codecommit.com/blog/ruby/implicit-conversions-more-powerful-than-dynamic-typing]Implicit Conversions: More Powerful than Dynamic Typing?[/url],我只对其中一部分进行了翻译。
  隐式转换是[url=Haskell type classes]Scala[/url]中实现的一种类似于Haskell type classes的类型系统,它使得Scala这种静态类型的语言具有某些“动态”的特性。下面用具体例子来说明。

[color=red]案例1[/color]:[color=blue]给String添加一个reduce方法,其返回值为字符串中大写字母组成的新字符串。[/color]
在Scala中,最终效果如下:
//Scala
val acronym = "Microsoft Certified Systems Engineer".reduce
println(acronym) // MCSE

  由于String是Java语言内置的类型,现在遇到的问题是:在静态语言中,我们不能在运行时往已经存在的类中动态添加方法。
  在Scala中,我们可以定义一个新的类型,使它具有所需要的方法,然后再顶一个一个从已有类型到新类型的隐式转换。然后Scala编译器将会在幕后实施其魔法。代码如下:
class MyStr(str:String) {
def reduce = str.foldLeft(""){ (s,c) =>
if(c.isUpperCase) s+c else s
}
}

implicit def str2MyStr(str:String) = new MyStr(str)


作为对照,我们看看在Ruby中的实现:
class String
def reduce
arr = unpack('c*').select { |c| (65..90).include? c }
arr.pack 'c*'
end
end

puts 'HyperText Transfer Protocol'.reduce # HTTP



[color=red]案例2[/color]:[color=blue]一个稍微复杂一点的问题:重载整数类型的[/color][color=red]<[/color][color=blue]操作符,使得它能与String比较,并且但String的长度小于该整数时返回true,否则返回false[/color]
  在Scala中,同样可以通过隐式转换机制来解决该问题。这一次我们使用比上面更简洁的形式:
//Scala,that's all
implicit def lessThanOverload(i: Int) = new {
def <(str: String) = str.length < i
}

  下面我们看看Ruby中如何解决这个问题,一个很自然的想法是玩Fixnum中添加所需的方法:
class Fixnum
def <(str)
str.size < self
end
end

  很不幸的是,这个看起来很对的方法是行不通的。每次调用整数的<操作符时都会进入一个死循环并很快导致堆栈溢出。
  我们可以将方法改写成如下以避免这个问题:
class Fixnum
def <(str)
self >= str.size
end
end

  这次不用担心堆栈溢出了,但新的问题出现了:
[quote]irb(main):006:0> 123 < 'test'
=> true
irb(main):007:0> 123 < 123
=> true[/quote]
  这个问题的最终Ruby解法是这样的:
class Fixnum
alias_method :__old_less_than__, '<'.to_sym
def <(target)
if target.kind_of? String
__old_less_than__ target.size
else
__old_less_than__ target
end
end
end

  囧,相比Scala,Ruby的解决方法显得即冗长且丑陋。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值