페이지

2015년 11월 2일 월요일

Scala2e Chapter5 Basic Types and Operations 5.1 Some basic types


Collectively, types Byte, Short, Int, Long, and Char are called integral types.
The integral types plus Float and Double are called numeric types.







Scala2e Chapter4 Classes and Objects 4.5 The Application trait

Scala provides a trit, scala.Application

import ChecksumAccumulator.calculate

object FallWinterSpringSummer extends Application {

   for(season <- fall="" list="" p="" spring="" winter="">       println(season + ": " + calculae(season))
}


Then instead of writing a main method, you place the code you would have put in the main method directly between the curly braces of the singleton object. That's it. You can compile and run this application just like any other.

Inheriting from Application is shorter than writing an explicit main method, but it also has some shortcomings.
First, you can't use this trait if you need to access command-line arguments, because the args array isn't available.
Second, because of some restrictions in the JVM threading model, you need an explicit main method if your program is multi-threaded.
Finally, some implementations of the JVM do not optimize the initialization code of an object which is executed by the Application trait. So you should inherit from Application only when your program is relatively simple and single-threaded.

Scala2e Chapter4 Classes and Objects 4.4 A Scala application

To run a Scala program, you must supply the name of a standalone signleton object with a main method that takes on parameter, an Array[String], and has a result type of Unit.

import ChecksumAccumulator.calculate

object Summer{
   def main(args: Array[String]){
       for(arg <- args="" p="">            println(arg + ": " +  calculate(arg))
    }
}

Scala implicitly imports members of packages java.lang and scala, as well as the members of a singlecton object named Predef, into every Scala source file. Predef, which resides in package scala, contains many useful methods. (println,assert...)

.scala files anything you want, no matter what Scala classes or code you put in them.
In general in the case of non=scripts, however, it is recommended style to name files after the classes they contain as in done in java, so that programmers can more easily locate classes by looking at file names.

A script, by contrast, must end in a result expression.

One way to do this is to use scalac, which is the basic Scala compiler, like this:

$scalac ChecksumAccumulator.scala summer.scala

This compiles your source files, but there may be a perceptible delay before the compilation finishes. The reason is that every time the compiler starts up, it spends time scanning the contents of jar files and doing other initial work before it even looks at the fresh source files you submit to it. Fro this reason, the Scala distribution also includes a Scala compiler daemon called fsc(for fast Scala compiler). You use it like this:

$fac ChecksumAccumulator.scala Summer.scala

If you ever want to stop the fsc daemon, you can do so with fsc -shutdown.

Scala2e Chapter4 Classes and Objects 4.3 Singleton objects

Scala connot have static members.
Instead, Scala has singleton objects.
except instead of the keyword class you use the keyword object.

import scala.collection.mutable.Map

object ChecksumAccumulator{

     private val cashe = Map[String, Int]()
     def ccalculate(s: String) : Int =
          if(cache.contains(s))
               cache(s)
          else {
               val acc = new CheckSumAccumulator
               for(c <- p="" s="">                   acc.add(c.toByte)
               val cs = acc.checksum()
               cache += (s -> cs)
                cs
          }
  }

If you are a Java programmer, on way to thick of singleton objects is as the home for any static methods you might have written in Java.

ChecksumAccumulator.calculate("Every value is an object.")

A singleton object is more than a holder of satic methods, however, It is a first-class object. You can think of a singleton object's name, therefore, as a "name tag" attached to the object:



Defining a singleton object doesn't define a type(at the Scala level of abstraction).
Singleton objects extends a superclass and can mix in traits. Given each singleton object is an instance of its superclasses and mixed-in traits, you can invoke its methods via these types, refer to it from variables of these types, and pass it to methods expecting these types.

One difference between classes and singleton objects is that singleton objects cannot take parameters, whereas classes can.

Because you can't instantiate a singleton object with the new keyword, you have no way to pass parameters to it.
Each singleton object is implemented as an instance of a synthetic class referenced from a static variable, so they have the same initialization semantics as Java statics.
In particular, a singleton object is initialized the first time some code accesses it.

A singleton object that does not share the same name with a companion class is called a standalone object.
   

Scala2e Chapter4 Classes and Objects 4.2 Semicolon inference

In a Scala program, a semicolon at the end of a statement is usually optional.

val s = "hello"; println(s)

The rules of semicolon inference

1. The line in questing ends in a word that would not be legal as the end of a statement, such as period or an infix ooperator.

2. The next line begins with a word that cannot start a statement.

3. The line ends while inside parentheses (...) or brackets [...], because these cannot contain multiple statements anyway.




Scala2e Chapter4 Classes and Objects 4.1 Classes, fields, and methods

A class is a blueprint for objects.
Once you define a class, you can create objects from the class blueprint with the keyword new.

class ChecksumAccumulator{
// class definition goes here
}

You can create ChecksumAccumulator objects with:

new ChecksumAccumulator


class ChecksumAccumulator{
    var sum = 0
}

val acc = new ChecksumAccumulator
val csa = new ChecksumAccumulator



acc.sum = 3



An object's instance variables make up the memory image of the object.
You can see this illustrated here not only in that you see two sum variables, but also that when you changed on, the other was unaffected.


//Won't compile, because acc is a val
acc = new ChecksumAccumulator

class ChecksumAccumulator{
   private var sum = 0
}


val acc = new ChecksumAccumulator
acc.sum = 5 //Won't comile, because sum is private


The way you make members public in Scala is by not explicity specifying any access modifier.

class ChecksumAccumulator{

    private var  sum = 0
    def add(b: Byte): Unit = {
      sum += b
    }

    def checksum(): Int = {
       return ~(sum & 0xFF) + 1
    }
}


Ay parameers to a method can be used inside the method. One important characteristic of method parameters in Scala is that they are vals, not vars.

def add(b : Byte) : Unit = {
   b = 1                // This won't complie, becase b is a val
   sum += b
 }

The recommended style for methods is in fact to avoid having explicit, and especially multiple smaller ones. On the other hand, design choices depend on the design context, and Scala makes it easy to write methods that have multiple, explicit returns if that's what you desire.

class ChecksumAccumulater {
   private var sum = 0
   def add(b: Byte) : Unit = sum += b
   def checksum() : Int = ~(sum & 0xFF) + 1
}

Methods with a result type of Unit, such as ChecksumAccumulator's add method, are executed for their side effects.
A side effect is generally defined as mutating state somewhere external to the method or performing an I/O action.


class ChecksumAccumulator{
   private var sum = 0
   def add(b: Byte) { sum += b }
   def checksum() : Int = ~(sum & 0xFF) + 1
}


One puzzler to watch out for is that whenever you leave off the equals sign before the body of a function, its result type will definitely be Unit.
This is true no matter what the body contains, because the Scala compiler can convert any type to Unit. For example, It the last result of a method is a String, but the method's result type is declared to be Unit, the String will be converted to Unit and its value lost.








Scala2e Chapter3 Next Steps in Scala - Step 12. Read lines from a file

In this section, you'll build a script that reads lines from a file and prints them out prepended with the number of characters in each line.

import scala.io.Source
if(argslength > 0){
   for(line <- args="" getlines="" p="" source.fromfile="">       println(line.length + "  "  + line)
   }
}else
   Console.err.println("Please enter filename")

To accomplish this, you can iterate through the lines twice. The first time through you'll determine the maximum width required by any line's character count. the second time through you'll print the output, using the maximum width calculated previously. Because you'll be iterating through the lines twice, you may as well assign them to a variable:

val lines = Source.fromFile(args(0)).getLines().toList

The lines variable, therefore, references a list of strings that contains the contents of the file specified on the command line.

def widthOfLength(s: String) = s.length.toString.length

with the function, you could calculate the maximum width liek this:

var maxWidth = 0
for(line <- lines="" p="">   maxWidth = maxWidth.max(widthOfLength(line))

import scala.io.Source

def widthOfLength(s:String) = s.length.toString.length

if(args.length > 0 ){
   val lines = Source.fromFile(args(0)).getLines().toList

   val longestLine = lines.reduceLeft(
       (a, b) => if(a.length > b.length ) a else b
   )
   val maxWidth = widthOfLength(longestLine)


   for(line <- lines="" p="">      val numSpaces = maxWidth - widthOfLength(line)
      val padding = " " * numSpaces
      println(padding + line.length + " | " + line)
   }
}
else
     Console.err.println("Please enter filename")