请选择 进入手机版 | 继续访问电脑版
楼主: Nicolle
4380 31

Scala Cookbook:Recipes for Object-Oriented and Functional Programming [推广有奖]

ReneeBK 发表于 2015-9-13 07:47:28 |显示全部楼层 |坛友微信交流群
  1. Matching Multiple Conditions with One Case Statement
  2. Problem
  3. You have a situation where several match conditions require that the same business logic be executed, and rather than repeating your business logic for each case, you’d like to use one copy of the business logic for the matching conditions.
  4. Solution
  5. Place the match conditions that invoke the same business logic on one line, separated by the | (pipe) character:
  6. val i = 5
  7. i match {
  8.   case 1 | 3 | 5 | 7 | 9 => println("odd")
  9.   case 2 | 4 | 6 | 8 | 10 => println("even")
  10. }
  11. This same syntax works with strings and other types. Here’s an example based on a String match:
  12. val cmd = "stop"
  13. cmd match {
  14.   case "start" | "go" => println("starting")
  15.   case "stop" | "quit" | "exit" => println("stopping")
  16.   case _ => println("doing nothing")
  17. }
复制代码

使用道具

ReneeBK 发表于 2015-9-13 07:48:26 |显示全部楼层 |坛友微信交流群
  1. Assigning the Result of a Match Expression to a Variable
  2. Problem
  3. You want to return a value from a match expression and assign it to a variable, or use a match expression as the body of a method.
  4. Solution
  5. To assign a variable to the result of a match expression, insert the variable assignment before the expression, as with the variable evenOrOdd in this example:
  6. val evenOrOdd = someNumber match {
  7.   case 1 | 3 | 5 | 7 | 9 => println("odd")
  8.   case 2 | 4 | 6 | 8 | 10 => println("even")
  9. }
  10. This approach is commonly used to create short methods or functions. For example, the following method implements the Perl definitions of true and false:
  11. def isTrue(a: Any) = a match {
  12.   case 0 | "" => false
  13.   case _ => true
  14. }
复制代码

使用道具

ReneeBK 发表于 2015-9-13 07:49:16 |显示全部楼层 |坛友微信交流群
  1. Accessing the Value of the Default Case in a Match Expression
  2. Problem
  3. You want to access the value of the default, “catch all” case when using a match expression, but you can’t access the value when you match it with the _ wildcard syntax.
  4. Solution
  5. Instead of using the _ wildcard character, assign a variable name to the default case:
  6. i match {
  7.   case 0 => println("1")
  8.   case 1 => println("2")
  9.   case default => println("You gave me: " + default)
  10. }
复制代码

使用道具

ReneeBK 发表于 2015-9-13 07:50:38 |显示全部楼层 |坛友微信交流群
  1. Using Pattern Matching in Match Expressions
  2. Problem
  3. You need to match one or more patterns in a match expression, and the pattern may be a constant pattern, variable pattern, constructor pattern, sequence pattern, tuple pattern, or type pattern.
  4. Solution
  5. Define a case statement for each pattern you want to match. The following method shows examples of many different types of patterns you can use in match expressions:
  6. def echoWhatYouGaveMe(x: Any): String = x match {

  7.   // constant patterns
  8.   case 0 => "zero"
  9.   case true => "true"
  10.   case "hello" => "you said 'hello'"
  11.   case Nil => "an empty List"

  12.   // sequence patterns
  13.   case List(0, _, _) => "a three-element list with 0 as the first element"
  14.   case List(1, _*) => "a list beginning with 1, having any number of elements"
  15.   case Vector(1, _*) => "a vector starting with 1, having any number of elements"

  16.   // tuples
  17.   case (a, b) => s"got $a and $b"
  18.   case (a, b, c) => s"got $a, $b, and $c"

  19.   // constructor patterns
  20.   case Person(first, "Alexander") => s"found an Alexander, first name = $first"
  21.   case Dog("Suka") => "found a dog named Suka"

  22.   // typed patterns
  23.   case s: String => s"you gave me this string: $s"
  24.   case i: Int => s"thanks for the int: $i"
  25.   case f: Float => s"thanks for the float: $f"
  26.   case a: Array[Int] => s"an array of int: ${a.mkString(",")}"
  27.   case as: Array[String] => s"an array of strings: ${as.mkString(",")}"
  28.   case d: Dog => s"dog: ${d.name}"
  29.   case list: List[_] => s"thanks for the List: $list"
  30.   case m: Map[_, _] => m.toString

  31.   // the default wildcard pattern
  32.   case _ => "Unknown"
  33. }
复制代码

使用道具

ReneeBK 发表于 2015-9-13 07:53:41 |显示全部楼层 |坛友微信交流群
  1. Using Case Classes in Match Expressions
  2. Problem
  3. You want to match different case classes (or case objects) in a match expression, such as when receiving messages in an actor.
  4. Solution
  5. Use the different patterns shown in the previous recipe to match case classes and objects, depending on your needs.
  6. The following example demonstrates how to use patterns to match case classes and case objects in different ways, depending primarily on what information you need on the right side of each case statement. In this example, the Dog and Cat case classes and the Woodpecker case object are different subtypes of the Animal trait:
  7. trait Animal
  8. case class Dog(name: String) extends Animal
  9. case class Cat(name: String) extends Animal
  10. case object Woodpecker extends Animal

  11. object CaseClassTest extends App {

  12.   def determineType(x: Animal): String = x match {
  13.     case Dog(moniker) => "Got a Dog, name = " + moniker
  14.     case _:Cat => "Got a Cat (ignoring the name)"
  15.     case Woodpecker => "That was a Woodpecker"
  16.     case _ => "That was something else"
  17.   }

  18.   println(determineType(new Dog("Rocky")))
  19.   println(determineType(new Cat("Rusty the Cat")))
  20.   println(determineType(Woodpecker))

  21. }
复制代码

使用道具

ReneeBK 发表于 2015-9-26 10:55:48 |显示全部楼层 |坛友微信交流群

使用道具

  1. 4.1. Creating a Primary Constructor

  2. Problem
  3. You want to create a primary constructor for a class, and you quickly find that the approach is different than Java.

  4. Solution
  5. The primary constructor of a Scala class is a combination of:

  6. The constructor parameters

  7. Methods that are called in the body of the class

  8. Statements and expressions that are executed in the body of the class

  9. Fields declared in the body of a Scala class are handled in a manner similar to Java; they are assigned when the class is first instantiated.

  10. The following class demonstrates constructor parameters, class fields, and statements in the body of a class:

  11. class Person(var firstName: String, var lastName: String) {

  12.   println("the constructor begins")

  13.   // some class fields
  14.   private val HOME = System.getProperty("user.home")
  15.   var age = 0

  16.   // some methods
  17.   override def toString = s"$firstName $lastName is $age years old"
  18.   def printHome { println(s"HOME = $HOME") }
  19.   def printFullName { println(this) }  // uses toString

  20.   printHome
  21.   printFullName
  22.   println("still in the constructor")

  23. }
  24. Because the methods in the body of the class are part of the constructor, when an instance of a Person class is created, you’ll see the output from the println statements at the beginning and end of the class declaration, along with the call to the printHome and printFullName methods near the bottom of the class:

  25. scala> val p = new Person("Adam", "Meyer")
  26. the constructor begins
  27. HOME = /Users/Al
  28. Adam Meyer is 0 years old
  29. still in the constructor
复制代码


使用道具

  1. 4.2. Controlling the Visibility of Constructor Fields

  2. Problem
  3. You want to control the visibility of fields that are used as constructor parameters in a Scala class.

  4. Solution
  5. As shown in the following examples, the visibility of constructor fields in a Scala class is controlled by whether the fields are declared as val, var, without either val or var, and whether private is also added to the fields.

  6. Here’s the short version of the solution:

  7. If a field is declared as a var, Scala generates both getter and setter methods for that field.

  8. If the field is a val, Scala generates only a getter method for it.

  9. If a field doesn’t have a var or val modifier, Scala gets conservative, and doesn’t generate a getter or setter method for the field.

  10. Additionally, var and val fields can be modified with the private keyword, which prevents getters and setters from being generated.

  11. See the examples that follow for more details.
复制代码

使用道具

  1. 4.3. Defining Auxiliary Constructors

  2. Problem
  3. You want to define one or more auxiliary constructors for a class to give consumers of the class different ways to create object instances.

  4. Solution
  5. Define the auxiliary constructors as methods in the class with the name this. You can define multiple auxiliary constructors, but they must have different signatures (parameter lists). Also, each constructor must call one of the previously defined constructors.

  6. The following example demonstrates a primary constructor and three auxiliary constructors:

  7. // primary constructor
  8. class Pizza (var crustSize: Int, var crustType: String) {

  9.   // one-arg auxiliary constructor
  10.   def this(crustSize: Int) {
  11.     this(crustSize, Pizza.DEFAULT_CRUST_TYPE)
  12.   }

  13.   // one-arg auxiliary constructor
  14.   def this(crustType: String) {
  15.     this(Pizza.DEFAULT_CRUST_SIZE, crustType)
  16.   }

  17.   // zero-arg auxiliary constructor
  18.   def this() {
  19.     this(Pizza.DEFAULT_CRUST_SIZE, Pizza.DEFAULT_CRUST_TYPE)
  20.   }

  21.   override def toString = s"A $crustSize inch pizza with a $crustType crust"

  22. }

  23. object Pizza {
  24.   val DEFAULT_CRUST_SIZE = 12
  25.   val DEFAULT_CRUST_TYPE = "THIN"
  26. }
  27. Given these constructors, the same pizza can be created in the following ways:

  28. val p1 = new Pizza(Pizza.DEFAULT_CRUST_SIZE, Pizza.DEFAULT_CRUST_TYPE)
  29. val p2 = new Pizza(Pizza.DEFAULT_CRUST_SIZE)
  30. val p3 = new Pizza(Pizza.DEFAULT_CRUST_TYPE)
  31. val p4 = new Pizza
复制代码

使用道具

  1. 4.4. Defining a Private Primary Constructor

  2. Problem
  3. You want to make the primary constructor of a class private, such as to enforce the Singleton pattern.

  4. Solution
  5. To make the primary constructor private, insert the private keyword in between the class name and any parameters the constructor accepts:

  6. // a private no-args primary constructor
  7. class Order private { ...

  8. // a private one-arg primary constructor
  9. class Person private (name: String) { ...
  10. As shown in the REPL, this keeps you from being able to create an instance of the class:

  11. scala> class Person private (name: String)
  12. defined class Person

  13. scala> val p = new Person("Mercedes")
  14. <console>:9: error: constructor Person in class Person cannot be accessed
  15. in object $iw
  16.        val p = new Person("Mercedes")
复制代码

使用道具

您需要登录后才可以回帖 登录 | 我要注册

本版微信群
加JingGuanBbs
拉您进交流群

京ICP备16021002-2号 京B2-20170662号 京公网安备 11010802022788号 论坛法律顾问:王进律师 知识产权保护声明   免责及隐私声明

GMT+8, 2024-3-28 22:34