一切都是Scala中的一个对象

时间:2013-03-27 21:12:12

标签: scala

我是Scala的新手并且听到很多东西都是Scala中的对象。我不知道的是“一切都是对象”的优势是什么?如果一切都不是对象,我不能做的事情是什么?欢迎举例。感谢

5 个答案:

答案 0 :(得分:4)

将“所有内容”作为一个对象的优势在于,抽象中断的情况要少得多。

例如,方法不是Java中的对象。所以,如果我有两个字符串,我可以

String s1 = "one";
String s2 = "two";
static String caps(String s) { return s.toUpperCase(); }
caps(s1);  // Works
caps(s2);  // Also works

因此,我们在制作大写字母的操作中抽象出字符串标识。但是,如果我们想要抽象出操作的身份 - 也就是说,我们将某些东西传递给一个String,它会返回另一个String但我们想要抽象出细节是什么呢?现在我们陷入困境,因为方法不是Java中的对象。

在Scala中,方法可以转换为 functions ,它们是对象。例如:

def stringop(s: String, f: String => String) = if (s.length > 0) f(s) else s
stringop(s1, _.toUpperCase)
stringop(s2, _.toLowerCase)

现在我们已经抽象出了对非空字符串执行字符串转换的想法。

如果这就是我们需要做的事情,我们可以列出操作等等并传递它们。

还有其他不那么重要的情况(对象与类,原始与非对象,值类等),但最重要的是崩溃方法和对象之间的区别,以便传递和抽象功能就像很容易传递和抽象数据。

答案 1 :(得分:3)

优点是您没有在您的语言中遵循不同规则的不同运算符。例如,在Java中执行涉及对象的操作,您使用调用代码的dot name技术(静态对象仍使用dot name技术,但有时使用this object或{{1推断)内置项(不是对象)使用不同的方法,即内置操作符操作。

static object

主要区别在于Number one = Integer.valueOf(1); Number two = Integer.valueOf(2); Number three = one.plus(two); // if only such methods existed. int one = 1; int two = 2; int three = one + two; 技术受多态性,运算符重载,方法隐藏以及Java对象可以做的所有好事的影响。 dot name技术是预定义的,完全不灵活。

Scala基本上将+运算符作为+运算符处理,并且定义了这些运算符与对象方法的强一对一映射,从而规避了dot name方法的不灵活性>。因此,在Scala 中,一切都是对象意味着所有都是一个对象,所以操作

 5 + 7

导致创建两个对象(一个5对象和一个7对象),使用参数7调用5对象的plus方法(如果我的scala内存正确地为我服务),并返回一个“12”对象作为5 + 7操作的值。

这一切都是一个对象在函数式编程环境中有很多好处,例如,代码块现在也是对象,可以传递来回的代码块(没有名称)作为参数,但仍然绑定严格类型检查(代码块只返回LongString或其他任何子类。

当它归结为它时,它使得某些类型的解决方案非常容易实现,并且通常由于不需要处理“移入原语,操纵,移出基元”编组代码来减轻效率低下。 / p>

答案 2 :(得分:3)

我想到的一个特定优势(因为您要求提供示例)是Java中的原始类型(int, boolean ...),Scala中的对象是您可以通过隐式转换添加功能的对象。例如,如果要向int添加toRoman方法,可以编写一个隐式类,如:

implicit class RomanInt(i:Int){
  def toRoman = //some  algorithm to convert i to a Roman representation
}

然后,您可以从任何Int字面调用此方法,如:

val romanFive = 5.toRoman  // V

通过这种方式,您可以“拉皮条”基本类型以使其适应您的需求

答案 3 :(得分:2)

除了他人提出的观点之外,我总是强调Scala中所有值的统一处理部分是一种错觉。在大多数情况下,这是一个非常受欢迎的错觉。 Scala非常聪明地尽可能地使用真正的JVM原语,并且只在必要时执行自动转换(通常称为装箱和拆箱)。

然而,如果自动装箱和拆箱的动态应用模式非常高,则可能存在与之相关的不期望的成本(存储器和CPU)。这可以通过使用 specialization 来部分缓解,当特定类型参数是(程序员指定的)原始类型时,它会创建泛型类的特殊版本。这样可以避免装箱和拆箱,但会以正在运行的应用程序中的.class个文件为代价。

答案 4 :(得分:0)

并非所有内容都是Scala中的对象,尽管Scala中的对象比Java中的类似物更多。

对象的优势在于它们是状态的包,它们也有一些与它们相关的行为。通过添加多态性,对象可以为您提供更改隐式行为和状态的方法。足够的诗歌,让我们进入一些例子。

if语句不是scala或java中的对象。如果是,您可以将其子类化,在其位置注入另一个依赖项,并使用它来执行诸如在您的代码使用if语句时记录到文件的内容。那不是很神奇吗?在某些情况下,它会帮助您调试内容,而在其他情况下,它会让您的头发变得白皙,然后才会发现由于某人覆盖if行为而导致的错误。

访问一个无对象的,有说服力的世界:对您最喜爱的OOP编程语言进行成像。想想它提供的标准库。那里有很多课程,对吧?他们提供定制方式,对吧?它们采用其他对象的参数,创建其他对象。您可以自定义所有这些。你有多态性。现在想象所有标准库都只是关键字。您将无法自定义,因为您无法覆盖关键字。你会被语言设计者决定实施的任何情况所困扰,而你在那里定制任何东西都会无助。这些语言存在,你很了解它们,它们是类似续集的语言。你几乎不能在那里创建函数,但是为了自定义SELECT语句的行为,必须出现包含最期望的特征的语言的新版本。这将是一个极端的世界,你只能通过向语言设计师询问新功能(你可能得不到,因为其他更重要的功能需要一些与你想要的功能不兼容的功能)来编程。

总之,并非所有内容都是scala中的对象:类,表达式,关键字和包肯定不是。然而,更多的东西,如功能。 什么是恕我直言,一个很好的经验法则是更多的对象等于更多的灵活性

P.S。例如,在Python中,更多的东西是对象(比如类本身,packages的类似概念(即python模块和包)。你会看到它是怎样的,黑魔法更容易做,而且带来好的和坏的后果。