迪杰斯卡拉算法
我已经通过Scala编程语言被介绍给不可变数据结构世界-写信给我,被介绍给FP世界听起来太冒昧。 尽管我不建议在日常项目中使用它,但我还是很感激我所学到的东西:我的Java代码现在绝对不一样了,因为Scala使我意识到了这两种语言的某些缺陷还有我的编码习惯
这是第1 周后在斯卡拉与Kotlin重点series.Other职位包括:
- Scala vs Kotlin:皮条客我的图书馆 (此职位)
- Scala vs Kotlin:运算符重载
- Scala vs Kotlin:内联和中缀
- 斯卡拉vsKotlin:多重继承与钻石问题
在本文中,我将探讨两者都如何提供一种改善现有 Java库使用率的方法。
斯卡拉
让我们从Scala开始,它是10年前创造的“ Pimp My Library ”一词。
Scala的方法基于conversion 。 考虑缺少所需行为的基本类型。 例如,Java的double
原语类型-映射到Scala的scala.Double
类型非常有限。
第一步是创建具有上述行为的新类型。 因此,Scala提供了RichDouble
类型来添加一些方法, 例如 isWhole()
。
第二步是提供一个隐式函数,将其从基本类型转换为改进类型。 此类函数的签名必须遵循以下规则:
- 具有基本类型的单个参数
- 返回改进的类型
- 被标记为
implicit
以下是Scala库如何声明Double
到RichDouble
转换函数的方法:
private[scala]abstractclassLowPriorityImplicits{
...
implicitdefdoubleWrapper(x:Double)=newruntime.RichDouble(x)
...
}
一种替代方法是创建一个隐式类 ,除其他要求外, 该类还必须具有一个带有基本类型单个参数的构造函数。
最后一步是将转换纳入范围 。 对于转换函数,这意味着将函数导入要使用转换的类文件中。 请注意,在这种特殊情况下,转换功能是自动导入的一部分(无需显式声明它)。
此时,如果未为类型定义函数,则编译器将查找导入的转换函数,该函数会将这种类型转换为提供该函数的新类型。 在这种情况下,类型将被转换功能替换。
valx=45d
valisWhole=x.isWhole// Double has no isWhole() function
// But there's a conversion function in scope which transforms Double to RichDouble
// And RichDouble has a isWhole() function
valisWhole=doubleWrapper(x).isWhole
Kotlin
我对使用Scala持谨慎态度的主要原因之一确实是隐性部分:与AOP一样,这使得对代码的推理变得更加困难。 AOP的顺势疗法可以挽救生命,广泛使用会适得其反。
Kotlin避开了隐式性:它提供了扩展方法 (和属性),而不是转换。
让我们分析一下如何向java.lang.Double
类型添加其他行为。
第一步是提供扩展功能:这是一个正常功能,但嫁接到了现有的类型上。 要添加与上述相同的isWhole()
函数,语法如下:
funDouble.isWhole()=this==Math.floor(this)&&!java.lang.Double.isInfinite(this)
至于Scala,第二步是将此功能引入范围。 从Scala开始,它是通过导入实现的。 如果在ch.frankel.blog
包的任何文件中定义了先前的功能:
importch.frankel.blog.isWhole
valx=45.0
valisWhole=x.isWhole// Double has no isWhole() function
// But there's an extension function in scope for isWhole()
valisWhole=x==Math.floor(x)&&!java.lang.Double.isInfinite(x)
注意扩展方法是静态解析的。
扩展实际上并不修改它们扩展的类。 通过定义扩展,您无需在类中插入新成员,而仅使新函数可在该类的实例上以点符号进行调用。
我们要强调的是,扩展功能是静态分配的,即,它们不是按接收者类型虚拟的。 这意味着被调用的扩展函数是由在其上调用该函数的表达式的类型确定的,而不是由在运行时对该表达式求值的结果的类型确定的。
结论
显然,Scala还有一个间接级别-转换。 我让任何人决定这是好事还是坏事。 对我来说,这使得推理代码变得更加困难。
另一个空白是附加功能的包装。 在Scala中,所有这些都属于扩展类型,可以整体导入,但必须在Kotlin中逐一导入。
迪杰斯卡拉算法