2017-03-26 2 views
3

Was sind die Vorteile der Syntax des Objektpakets gegenüber dem einfachen Hinzufügen von Funktionen und Variablen zu einem Paket?Motivation hinter den Scala-Paketobjekten

Beispiel:

package object something { 
    def hello = 0 
} 

package something { 

} 

Warum nicht einfach:

package something { 
    def hello = 0 
    // other classes and such 
} 
+0

Nicht sicher, was Sie mit "einfach lassen Sie Funktionen und Variablen zu einem Paket hinzufügen" meinen. Das Paketobjekt soll Konstanten innerhalb eines Pakets bereitstellen. –

+0

hinzugefügt ein Beispiel. – Derlin

Antwort

6

Sie noch einen Schritt weiter gehen könnte: warum Pakete überhaupt, wenn wir object s haben?

Scala soll als eine "gehostete Sprache" nützlich sein, d. H. Eine Sprache, die gut spielen kann und auf der Plattform einer anderen Sprache gehostet wird. Die ursprünglichen Implementierungen von Scala erfolgten auf der Java-Plattform und der ISO Common Language Infrastructure-Plattform (bzw. deren primären Implementierungen, .NET und Mono). Heute haben wir auch eine Implementierung auf der ECMAScript-Plattform (Scala.js), und die Java-Plattform-Implementierung kann beispielsweise auch auf Android verwendet werden. Sie können sich auch andere interessante Plattformen vorstellen, auf denen Sie Scala, z. die Windows-UWP-Plattform, die Swift/Objective-C/Core Foundation/macOS/iOS/tvOS/watchOS Plattform, die Gnome/GObject Plattform, die Qt/C++ Plattform etc.

Scala nicht nur wollen laufen auf diesen Plattformen will sie zwei erfüllen, oft gegensätzliche Ziele:

  • Hochleistungs
  • enge Integration mit einem "native" fühlen

S o, in Scala, Implementierung betrifft sind Teil des Sprachdesigns. (Rich Hickey, der Designer von Clojure, sagte einmal in einem Vortrag "Die JVM ist nicht ein Implementierungsdetail", das gleiche gilt für Scala.) Ein gutes Beispiel sind richtige Tail Calls: Um richtige Tail Calls zu unterstützen, Scala Sie müssten ihren eigenen Stack verwalten, anstatt den nativen Call-Stack der Host-Plattform auf Plattformen wie der JVM zu verwenden, was jedoch bedeutet, dass Sie Scala-Code nicht mehr einfach von anderem Code auf der Plattform aufrufen können und umgekehrt. Also, während richtige Tail-Calls wäre schön zu haben, setzt sich Scala für die weniger leistungsfähige richtige sofortige Tail-Rekursion.

Theoretisch braucht nur Scala object s, trait s, Methoden, type s, und Wege (. und #). Alles andere ist im Grunde nur dazu da, die Integration mit der Host-Plattform zu erleichtern. Hierzu gehören beispielsweise null, class es und package s.

Im Idealfall sollte es eine einfache Zuordnung von Host-Plattform-Konstrukten zu Scala-Konstrukten und umgekehrt geben. So gibt es beispielsweise eine einfache Zuordnung zwischen Scala-Methoden und JVM-Methoden. Es gibt eine einfache Zuordnung zwischen JVM-Schnittstellen und Scala-Merkmalen mit nur abstrakten Elementen. Es gibt keine einfache Zuordnung zwischen Scala-Merkmalen und JVM-Klassen, weshalb Scala das (redundante) Klassenkonzept hat. Und ebenso gibt es keine einfache Zuordnung zwischen Scala object s und JVM package s (oder CLI namespace s), weshalb Scala das (redundante) Konzept von package hat.

Aber wir würden wirklich wie package s (das sind immerhin so etwas wie Scala object s) Mitglieder sowie zu haben. Aber JVM package s und CLI namespace s können keine Mitglieder haben außer interface s und class es, und da wir sie nur in Scala für die Kompatibilität mit der Host-Plattform eingeführt haben, macht es einfach keinen Sinn, sie mit der Host-Plattform inkompatibel zu machen indem Sie ihnen Mitglieder hinzufügen.

Also, wir führen ein weiteres separates Konzept ein, das package object, das die Mitglieder enthält, die wir zu package s hinzufügen möchten, aber nicht, wegen der Interoperabilität der Hostplattform.

tl; dr:

  • wir haben package s wegen Interop (obwohl wir bereits object s haben, die alle die gleichen Dinge wie package s tun können)
  • möchten wir package s haben Mitglieder
  • package s können nicht Mitglieder haben, weil Interop
  • so, wir haben package object s als Begleiter zu package s
+0

danke für die Antwort. Der Grund liegt also nur in den Implementierungsbeschränkungen. Ich fragte mich, ob dies auch das Durcheinander verhindern sollte, dass Paketmethoden/Felder in mehrere Dateien verteilt waren. – Derlin

+0

@Derlin Sie könnten theoretisch alle Top-Level-Defs, Vals, Typen, ... aus verschiedenen Dateien nehmen und sie zu einem Paketobjekt zusammenstellen. Aber ich denke, das würde Probleme bei der inkrementellen und separaten Kompilierung verursachen. –