Schweitzer Fachinformationen
Wenn es um professionelles Wissen geht, ist Schweitzer Fachinformationen wegweisend. Kunden aus Recht und Beratung sowie Unternehmen, öffentliche Verwaltungen und Bibliotheken erhalten komplette Lösungen zum Beschaffen, Verwalten und Nutzen von digitalen und gedruckten Medien.
Scala borrows many of its syntax and control structures from various other languages. Methods are declared in Algol/C style with the addition of features such as optional braces, and semicolons to reduce code boilerplate.
Scala syntax also has features such as expressions for statements, local type inference, suffix/infix notation, and implicit return statements, which make typical idiomatic Scala code look like dynamic languages such as Lisp/Python/Ruby, but with the added benefit of strong static typing.
The expressive nature of Scala's syntax is useful to create custom DSL's, with the most notable example being Scala's own XML library. Scala also features several forms of inheritance (traits, classes, objects), which can be combined in various ways to structure composition in your code in a more natural and elegant way. This combined with a strong support for functional programming, syntactic sugar (for comprehension), and type inference makes it possible to create very terse domain specific code that is also type safe.
This chapter provides a broad overview of the various parts of Scala's design and syntax, as well as the features that are expected in modern generic programming languages (control of scoping, string interpolation, encapsulation, and modules).
Scala is first and foremost a statically typed language, which is similar to other statically typed languages you can annotate types for:
Below is a code sample to demonstrate these types of annotations:
val s: String // type definition on variable declaration def doSomething(s: String) // type definition in a parameter def doSomething: String // type definition for return type of a function class SomeClass(s: String) // type definition in a class constructor definition type MyString = String // type aliasing
A significant reason why Scala requires mandatory type signatures is that it's very difficult to provide a practical implementation of global type inference in a statically typed language that supports subtyping. Thankfully, while Scala mandates that you provide type signatures for method parameters and type definitions, for variable declarations inside function/method bodies it features local type inference. This drastically reduces the amount of boilerplate code when it comes to function/method bodies. Here is an example of local type inference in action.
def doSomething(input: String) = { val l = List(1,3,5) val summed = l.sum val asString = summed.toString + input asString.toUpperCase }
As you can see for variable declarations, you don't need to specify their respective types. To manually specify the types, do the following:
def doSomething(input: String): String = { val l: List[Int] = List(1,3,5) val summed: Int = l.sum val asString: String = summed.toString + input asString.toUpperCase() }
One bonus of specifying types for function arguments is that they also act as a form of documentation, which is particularly helpful. Return types of functions are also optional; however, it is encouraged to annotate them for documentation/clarity reasons. Due to Scala's generic code functionality, it is possible to have expressions that return different values in unexpected scenarios. One good example is Int's versus Double:
Int
Double
def f = 342342.43 def f_v2 = 342342 f == 342342 // returns true f_v2 == 342342 // return false
Since f and f_v2 don't have their return types annotated, we aren't aware of what types they can return (let's assume you don't know what the actual values of f and f_v2 are). This means that the f == 342342 expression returns something else compared to f_v2 == 342342. If, however, you know the return types of f and f_v2, you can do the following:
f
f_v2
f == 342342
f_v2 == 342342
def f: Double = 342342.43 def f_v2: Int = 342342
As a user, you know that the return type of f is a Double, so don't compare it with an Int when asking for equality ( since it's a Float by extension you should provide custom equality with a delta).
Manual type signatures can also be used to force the type of a declaration. This is similar to the typecast feature in languages like Java or C; however, it's more powerful due to type conversions available in Scala. A simple example in Scala is to assign a Long type to an integer literal.
val l: Long = 45458
By default, if you use a number literal in Scala it defaults to an Int. Note that it is also possible to use the number based suffix like so:
val l = 45458L
Arguably, the type annotation is more idiomatic, especially for custom types that may not have literal operators.
Scala has an incredibly powerful feature called implicits. When you ask for a value implicitly, such as a method parameter, or the implicit keyword you are telling the Scala compiler to look for a value that has the same type in scope. This is unlike the explicit value, where you need a type to specify when it's called/used. A practical use case for implicits is providing an API key for a REST web service. The API key is typically only provided once, so an implicit is a good use case in this instance, since you only need to define and import it once.
implicit
case class ApiKey(id: String)
Since implicits are found by their type you need to create a new type, in this case ApiKey. Now let's define a method that makes a HTTP call.
ApiKey
import scala.concurrent.Future def getUser(userId: Long)(implicit apiKey: ApiKey): Future[Option[User]] = ???
In order to call this function you must make sure that an implicit ApiKey is visible in the scope. Let's first make an instance of ApiKey and place it in an object.
object Config { implicit val apiKey = ApiKey(System.getenv("apiKey")) }
Whenever you call getUser, ApiKey needs to be visible, and the code should look something like this:
getUser
import Config._ // This imports everything in Config, including implicits object Main extends App { val userId = args(0).toLong getUser(userId) }
It's also possible to supply an implicit argument explicitly.
object Main extends App { val userId = args(0).toLong val apiKey = ApiKey(args(1)) getUser(userId)(apiKey) }
Implicits can be used to make automatic conversions between types; however, such usage is considered advanced and should be done sparingly, because it's easy to abuse code that uses these features. A prominent use of implicit conversions is in DSLs. For example, if you have a trivial DSL that attempts to represent SQL queries, you might have something like this:
Users.filter(_.firstName is "Bob")
In this case, _.firstName may be a different type from a String (in this example, let's say it has type Column[String]). And it can only work on types of Column[String]:
_.firstName
String
Column[String]
val columnStringImplementation = new Column[String] { def is(other: Column[String]): EqualsComparison = ??? }
To compare two instances of Column[String] (to see if they are equal) you want an implicit conversion of String to Column[String], so that you don't have to write:
Users.filter(_.firstName is ColumString("Bob"))
To do this you need to define the following:
implicit def stringToColumnStringConverter(s: String): Column[String] = ???
In this case, when you import your stringToColumnStringConverter, it will automatically convert any instances of String to Column[String] if it's required to do so. Since the is method only works on Column[String], the compiler will try to see if there is an implicit conversion available for the String "BoB," so it can satisfy the method signature for is.
stringToColumnStringConverter
is
Implicit classes are a type safe solution that Scala provides for monkey patching (extending an existing class, or in Scala's case, a type without having to modify the existing source of the type). Let's try this by adding a replaceSpaceWithUnderScore method to a String.
replaceSpaceWithUnderScore
object Implicits { implicit class StringExtensionMethods(string: String) { def replaceSpaceWithUnderScore = string.replaceAll(" ","_") } }
Like the previous example, you need to import this class to make it available:
import Implicits._ "test this string".replaceSpaceWithUnderScore // returns test_this_string
Scala has a feature called case class, which is a fundamental structure to represent an immutable data. A case class contains various helper methods, which provide automatic...
Dateiformat: ePUBKopierschutz: Adobe-DRM (Digital Rights Management)
Systemvoraussetzungen:
Das Dateiformat ePUB ist sehr gut für Romane und Sachbücher geeignet – also für „fließenden” Text ohne komplexes Layout. Bei E-Readern oder Smartphones passt sich der Zeilen- und Seitenumbruch automatisch den kleinen Displays an. Mit Adobe-DRM wird hier ein „harter” Kopierschutz verwendet. Wenn die notwendigen Voraussetzungen nicht vorliegen, können Sie das E-Book leider nicht öffnen. Daher müssen Sie bereits vor dem Download Ihre Lese-Hardware vorbereiten.Bitte beachten Sie: Wir empfehlen Ihnen unbedingt nach Installation der Lese-Software diese mit Ihrer persönlichen Adobe-ID zu autorisieren!
Weitere Informationen finden Sie in unserer E-Book Hilfe.