(Scala) 可以包含列表作为元素的列表
(Scala) Lists that can contain lists as elements
我已经编码两年了。我不能说我是专家。
我参加了使用 Common Lisp 的函数式编程课程。作为一种“新”语言,我听说过很多关于 Scala 的好消息,并且想学习它。我读了一本基础知识的书,想将我们在 Lisp 中所做的所有代码重写到 Scala 中。几乎所有的代码都通过列表,这是我发现问题的地方。大多数问题我可以通过递归遍历我将其设置为 List[Any]
的列表来解决 - 例如:
def reverse(thelist: List[Any]):List[Any].....
但是我发现除了 .isInstanceOf[List[Any]]
之外,没有特定的方法来检查列表的头部是否是列表本身
起初还可以,但现在我遇到了问题。 Any
不是很具体,尤其是在比较元素时。如果我想有一个等效列表,比方说,只有 Int
,我可以创建一个 List[Int]
,它只能将 Int
值作为元素,none可以是 List[Int] 本身。换一种方式,写 List[List[Int]]
也有同样的问题,但反过来,因为每个元素都必须是 List
。
作为解决方案,我尝试将原始列表设置为 List[Either[Int,List[Int]]]
,但这只会产生更多问题,因为现在我必须不断地写 .isInstanceOf
和 .asInstanceOf
我的 ifs 和递归调用,这很耗时并且使代码更难理解。但即使 List[Either[Int,List[Int]]]
也是一个临时解决方案,因为它只深入一层。一个列表可以包含一个列表,一个列表可以包含一个列表……等等。
Scala 是否提供了我还不知道的更优雅的解决方案,例如以某种方式使用 类 或对象,或者简单优雅的解决方案,或者我是否坚持编写这种代码?为了使我的问题更具体,Scala 中是否有一种方法可以定义一个列表,该列表可以但不必包含与元素类型相同的列表?
Scala 不仅仅是具有不同语法的 Common Lisp。对一切都使用列表是 Lisp 特有的东西,而不是你在其他语言中做的事情。
在 Scala 中,将异构列表用于任何事情都是不正常的 — List[Any]
。如果您愿意,当然可以,但这不是通常编写 Scala 代码的方式。当您刚刚开始学习这门语言时,这当然不是您应该编写的那种代码。
包含数字和列表混合的列表并不是真正的列表——它是一棵树。在 Scala 中,我们根本不使用 List
来表示树——我们定义了一个合适的树数据类型。任何介绍 Scala 的文本都包含这方面的示例。 (例如,参见 chapter 15 of Programming in Scala 中的表达式树。)
至于您的 reverse
示例,在 Scala 中我们通常不会写:
def reverse(thelist: List[Any]): List[Any]
相反,我们写:
def reverse[T](theList: List[T]): List[T]
适用于 List[Any]
但也适用于更具体的类型,例如 List[Int]
.
如果您坚持以另一种方式进行,那么您并不是在真正学习 Scala — 您是在与它抗争。任何时候您认为需要 Any
或 List[Any]
,都有更好、更惯用、更像 Scala 的解决方案。
在 Scala 代码中使用 asInstanceOf
或 isInstanceOf
也不正常。它们有意使用长而晦涩的名称 — 除了在极少数情况下,它们不会被使用。
改为使用模式匹配。它为您完成了 isInstanceOf
和 asInstanceOf
的等效操作,但更简洁且更不容易出错。同样,任何介绍 Scala 的文本都应该很好地涵盖什么是模式匹配以及如何使用它(例如 chapter 15 again)。
我已经编码两年了。我不能说我是专家。
我参加了使用 Common Lisp 的函数式编程课程。作为一种“新”语言,我听说过很多关于 Scala 的好消息,并且想学习它。我读了一本基础知识的书,想将我们在 Lisp 中所做的所有代码重写到 Scala 中。几乎所有的代码都通过列表,这是我发现问题的地方。大多数问题我可以通过递归遍历我将其设置为 List[Any]
的列表来解决 - 例如:
def reverse(thelist: List[Any]):List[Any].....
但是我发现除了 .isInstanceOf[List[Any]]
起初还可以,但现在我遇到了问题。 Any
不是很具体,尤其是在比较元素时。如果我想有一个等效列表,比方说,只有 Int
,我可以创建一个 List[Int]
,它只能将 Int
值作为元素,none可以是 List[Int] 本身。换一种方式,写 List[List[Int]]
也有同样的问题,但反过来,因为每个元素都必须是 List
。
作为解决方案,我尝试将原始列表设置为 List[Either[Int,List[Int]]]
,但这只会产生更多问题,因为现在我必须不断地写 .isInstanceOf
和 .asInstanceOf
我的 ifs 和递归调用,这很耗时并且使代码更难理解。但即使 List[Either[Int,List[Int]]]
也是一个临时解决方案,因为它只深入一层。一个列表可以包含一个列表,一个列表可以包含一个列表……等等。
Scala 是否提供了我还不知道的更优雅的解决方案,例如以某种方式使用 类 或对象,或者简单优雅的解决方案,或者我是否坚持编写这种代码?为了使我的问题更具体,Scala 中是否有一种方法可以定义一个列表,该列表可以但不必包含与元素类型相同的列表?
Scala 不仅仅是具有不同语法的 Common Lisp。对一切都使用列表是 Lisp 特有的东西,而不是你在其他语言中做的事情。
在 Scala 中,将异构列表用于任何事情都是不正常的 — List[Any]
。如果您愿意,当然可以,但这不是通常编写 Scala 代码的方式。当您刚刚开始学习这门语言时,这当然不是您应该编写的那种代码。
包含数字和列表混合的列表并不是真正的列表——它是一棵树。在 Scala 中,我们根本不使用 List
来表示树——我们定义了一个合适的树数据类型。任何介绍 Scala 的文本都包含这方面的示例。 (例如,参见 chapter 15 of Programming in Scala 中的表达式树。)
至于您的 reverse
示例,在 Scala 中我们通常不会写:
def reverse(thelist: List[Any]): List[Any]
相反,我们写:
def reverse[T](theList: List[T]): List[T]
适用于 List[Any]
但也适用于更具体的类型,例如 List[Int]
.
如果您坚持以另一种方式进行,那么您并不是在真正学习 Scala — 您是在与它抗争。任何时候您认为需要 Any
或 List[Any]
,都有更好、更惯用、更像 Scala 的解决方案。
在 Scala 代码中使用 asInstanceOf
或 isInstanceOf
也不正常。它们有意使用长而晦涩的名称 — 除了在极少数情况下,它们不会被使用。
改为使用模式匹配。它为您完成了 isInstanceOf
和 asInstanceOf
的等效操作,但更简洁且更不容易出错。同样,任何介绍 Scala 的文本都应该很好地涵盖什么是模式匹配以及如何使用它(例如 chapter 15 again)。