gpt4 book ai didi

scala - 在 Scala 中使用类型类的缺点

转载 作者:行者123 更新时间:2023-12-01 12:43:04 25 4
gpt4 key购买 nike

有一些框架完全采用了类型类模式。 scalaz 和 shapeless 就是很好的例子。所以在某些情况下,类型类肯定比普通的 Java 类和多态性更可取。

我敬畏隐含证据的表达能力,我很好奇为什么这种方法缺乏实际应用。是什么原因迫使 Scala 程序员使用基本类。类型类显然会耗费冗长和运行时间,但还有其他原因吗?

我之前没有 java 经验就开始使用 scala,想知道我是否错过了经典 scala-java 类可能提供的一些基本好处。

我正在寻找一些引人注目的用例,以显示类型类不足或无效的领域。

最佳答案

类型类和继承以不同的方式实现重用。继承擅长为更改的内部结构提供正确的功能。

class Foo { def foo: String = "foo" }
def fooUser(foo: Foo) { println(foo.foo) }

class Bar extends Foo {
private var annotation = List.empty[String]
def annotate(s: String) { annotation = s :: annotation }
override def foo = ("bar" :: annotation.map("@" + _)).mkString(" ")
}

现在,如果您给他们一个 Bar,每个使用 Foo 的人都能够得到正确的值,即使他们只知道类型是一个 >富。您不必预料到您可能需要可插入功能(除非不标记 foo final)。您不需要跟踪类型或继续向前传递见证实例;你只要用 Bar 代替 Foo 就可以了。这是一个大问题。如果您想要一个具有易于修改的功能的固定接口(interface),那么继承就是您的选择。

相比之下,当您拥有一组具有易于修改的接口(interface)的固定数据类型时,继承就不那么好了。排序就是一个很好的例子。假设您要对 Foo 进行排序。如果你尝试

class Foo extends Sortable[Foo] {
def lt(you: Foo) = foo < you.foo
def foo = "foo"
}

您可以将它传递给任何可以排序 Sortable 的东西。但是如果你想按名称的长度而不是标准排序怎么办?嗯,

class Foo extends LexicallySortable[Foo] with LengthSortable[Foo] {
def lexicalLt(you: Foo) = foo < you.foo
def lengthLt(you: Foo) = foo.length < you.foo.length
def foo = "foo"
}

这很快就会变得毫无希望,特别是因为您必须寻找 Foo 的所有子类并确保它们得到正确更新。将小于计算推迟到可以根据需要换出的类型类会好得多。 (或者到一个常规类,您必须始终显式引用它。)这种自动选择的功能也很重要。

你不能真正用一个替换另一个。当您需要轻松地将新类型的数据合并到固定接口(interface)时,请使用继承。当您需要几种底层数据但需要轻松提供新功能时,请使用类型类。当您两者都需要时,无论采用哪种方式,您都将需要做很多工作,因此请多多品尝。

关于scala - 在 Scala 中使用类型类的缺点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22566914/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com