Seventh step: Parameterized array with type
You can instantiate an object or class instance using new in Scala. When you instantiate an object in Scala, you can parameterize it with values and types: parameterize. Parameterization means "set" it when you create an instance. Parameterize an instance with a value by passing the object in parentheses to the constructor of the instance. For example, the following Scala code instantiates a new Java.math.BigInteger and uses the value "12345" parameterization:
new Java.math.BigInteger ("12345")
Parameterize an instance by setting one or more of the types in square brackets. Parameterize an instance by setting one or more of the types in square brackets. Code 3.1 shows an example. In this example, Greetstrings is the value of type array[string] (string array) and is parameterized by the value 3 in the first line of code, making its initial length 3. If you execute the code in code 3.1 as a script, you will see another hello, world! message. Note that when you parameterize an instance with both a type and a value, the type first appears in square brackets, followed by the value in parentheses.
val greetstrings = new array[string] (3 )
Greetstrings (0 ) = " hello
Greetstrings (1 ) = Span style= "color: #800000;" > " "
Greetstrings (2 ) = world!\n "
for (i <-0 to 2 )
Print (Greetstrings (i))
As mentioned earlier, thearray in Scala is accessed by placing the index in parentheses rather than in square brackets like Java . So the 0th element of the array is greetstrings (0), not greetstrings[0].
These three lines of code illustrate the important concepts of understanding how Scala sees Val's meaning. When you define a variable with Val, the variable cannot be re-assigned, but the object it points to can still be changed secretly. So in this case, you can't re-assign the greetstrings to a different array; greetstrings will always point to the same array[string] instance that it was initialized to point to. But you can modify the elements of that array[string] over and over again, so the array itself is mutable.
The last two lines of code 3.1 contain a for expression used to output each greetstrings array element sequentially.
for 0 2 ) Print (Greetstrings (i))
The first line of code for this for expression demonstrates another common rule for Scala: If the method takes only one argument, you can call it without a dot or parenthesis . The to in this example is actually a method with an int parameter. Code 0 to 2 is converted to a method call (0). to (2). Note that this syntax only works if you display the recipient of the specified method call. It is not possible to write Pringln 10, but it can be written as "Console println 10".
Technically, Scala has no operator overloading because it doesn't have a traditional operator. Instead, characters such as +,-,* and/are used to make the method name . So, when you enter 1 + 2 in the Scala interpreter in the first step, you are actually calling up a method named + on int object 1 and passing 2 as a parameter to it. As shown in 3.1, you can also use the traditional method invocation syntax to write 1 + 2 instead (1). + (2).
Another important idea shown here is that you can see why arrays are accessed using parentheses in Scala. Compared to Java, Scala has few exceptions. Arrays are just like the other classes in Scala, and are simply implementations of classes. When you use parentheses outside of one or more values or variables, Scala converts it to a method call called apply. So Greetstrings (i) is converted into greetstrings.apply (i). So the elements in Scala that access the array are just the same as the other method calls. This principle is not confined to arrays: Any application of an object to some of the arguments in parentheses will be converted to a call to the Apply method. The premise is, of course, that this type actually defines the Apply method. So this is not a special case, but a general rule.
Similarly, when assigning a value to a variable with parentheses and including one to several arguments, the compiler translates it into a call to the Update method of the object with the parentheses and the right of the equals sign. For example
Greetstrings (0"Hello"
will be converted to
Greetstrings.update (0"Hello")
Therefore, the following Scala code is consistent with your code semantics in code 3.1:
Val greetstrings =NewArray[string] (3) Greetstrings.update (0,"Hello") Greetstrings.update (1,", ") Greetstrings.update (2,"world!\n") for(I <-0. to (2) ) print (greetstrings.apply (i) )
Scala pursues the simplicity of concepts in everything from arrays to expressions, including objects with methods. You don't have to remember too many exceptions, such as the differences between primitive types in Java and the corresponding wrapper classes, or between arrays and normal objects. And this unification does not undermine the important performance cost. The Scala compiler uses Java arrays, primitive types, and native mathematical types that can exist in the compilation completion code. Although the example you see so far in this step is well-compiled, Scala provides a more concise way to create and initialize arrays that can often be used in your real code. It looks like it was shown in code 3.2. This line of code creates a new array of length 3, initialized with the incoming string "zero", "one" and "two". The compiler infers that the type of the array is array[string], because you pass the string to it.
Val numnames = Array ("zero""one""and" " )
What you actually do in code 3.2 is to invoke a factory method called apply, which creates and returns a new array. The Apply method is defined with a variable number of parameters on the associated object of the array: companion object. If you are a Java programmer, you can think of this as an increase in the array class using a static method called apply. The more verbose way to invoke the same apply method is:
Val numNames2 = array.apply ("zero""one"" ")
Eighth Step: Using List
Methods should not have side effects is a very important concept of functional style programming. The only effect of the method should be to evaluate and return a value. The advantage of working in this way is that the methods are rarely entangled and therefore more reliable and reusable. Another benefit (in the static type language) is that everything passed in to the outgoing method is checked by the type checker, so logic errors are more likely to behave themselves as type errors. Applying the philosophy of functional programming to the object world means making objects immutable.
As you can see, the Scala array is a mutable sequence in which all objects share the same type. Let's say array[string] contains only String. Although you cannot change the length of an array after instantiation, its element value is variable. Therefore, the array is a mutable object.
When it comes to the sharing of immutable object sequences of the same type, Scala's list class is. Like arrays, list[string] contains just String. Scala's List,scala. List, unlike Java's java.util.List, is always immutable (and the list in Java is mutable). More generally, Scala's list is designed for functional style programming. Creating a list is simple. The Code 3.3 shows:
Val onetwothree = List (123)
The code in Code 3.3 completes a new Val called Onetwothree and has been initialized with a new list[int with integer element values of 1, 2, and 3]. Because the list is immutable, they behave like a Java string: When you invoke a method on a list, it seems that the list of the name refers to a change, and in fact it simply creates a list with the new value and returns. For example, the list has a method called ":::" To implement the overlay function. You can use this:
Val onetwo = list (12= List (34=" " " were not mutated. "
println ( "" "is a new List. ) ")
If you execute this script, you will see:
List (12) and list (34) were not mutated. Thus, List (1234isnew List.
Perhaps the most commonly used operator of the list is the pronunciation of "cons":: '. Cons a new element to the front of the existing list, and then returns a list of results. For example, if you execute this script:
Val twothree = List (231 :: Twothree println (Onetwothree)
You will see:
List (123)
Note: The expression "1:: Twothree",:: Is the method of its right operand, list twothree. You may wonder: there's something wrong with the relevance of the method, but it's just a simple rule to remember: If a method is used as an operator callout, such as a * B, then the method is called by the left operand, like a.* (b)-unless the method name ends with a colon. In this case, the method is called by the right-hand operand. So, 1:: Twothree,:: The method is called by Twothree, passed in 1, like this: Twothree.::(1).
Since the shortcut to defining an empty class is nil, one way to initialize a new list is to use all the elements with the Cons operator, nil as the last element. For example, the following script will produce the same output as the previous one, "List (1, 2, 3)"
1 2 3 :: Nil println (Onetwothree)
The reason to use nil at the end is:: Is the method defined on the list class. If you want to just write 1:: 2:: 3, because 3 is of type int, there is no: method, resulting in a compile loss.
Scala's list wraps up a lot of useful methods, and table 3.1 lists some of them. The full strength of the list will be released in the 16th chapter.
Why doesn't the list support append?
The class list does not provide a append operation because the time-consuming of append will grow linearly as the list grows, while using: The prefix takes only a constant amount of time. If you want to construct the list by adding elements, your choice is to prefix them in, and then call reverse when you're done, or use Listbuffer, a mutable list that provides append operations, and call ToList when you're done. Listbuffer will be described in section 22.2.
Table 3.1 Some methods and functions of type list
Method name |
Method effect |
List () or Nil |
Empty list |
List ("Cool", "Tools", "rule") |
Create a new list[string with three values "Cool", "Tools" and "rule" |
Val thrill = "would":: "Fill":: "until":: Nil |
Create a new list[string with three values "would", "fill" and "until" |
List ("A", "B")::: List ("C", "D") |
Overlay two lists (returns new list[string with "a", "B", "C" and "D") |
Thrill (2) |
Returns an element with an index of 2 (based on 0) on the Thrill list (returns "until") |
Thrill.count (s = s.length = = 4) |
Counts the number of string elements with a length of 4 (returns 2) |
Thrill.drop (2) |
Returns the list of thrill that removed the first 2 elements (return list ("until")) |
Thrill.dropright (2) |
Returns a list of thrill ("would") after removing the 2 elements |
Thrill.exists (s = = s = = "until") |
Determines if there is a string element with a value of "until" in Thrill (returns True) |
Thrill.filter (s = s.length = = 4) |
Returns a list of all elements of length 4 (return list ("would", "fill") |
Thrill.forall (s = S.endswith ("1")) |
Identifies if all elements in the thrill list End with "L" (returns True) |
Thrill.foreach (S-= print (s)) |
Execute PRINT statement ("Willfilluntil") for each string in the thrill list |
Thrill.foreach (print) |
Same as before, but more concise (IBID.) |
Thrill.head |
Returns the first element of the thrill list (returns "would") |
Thrill.init |
Returns a list of the elements of the thrill list other than the last (return list ("would", "fill") |
Thrill.isempty |
Indicates whether the thrill list is empty (returns false) |
Thrill.last |
Returns the last element of the thrill list (returns "until") |
Thrill.length |
Returns the number of elements in the Thrill list (returns 3) |
Thrill.map (s = + s + "Y") |
Returns a list of "Y" elements that are added to each string element in the Thrill list ("Willy", "filly", "Untily") |
Thrill.mkstring (",") |
Create a string with the elements of the list (return "would, fill, until") |
Thrill.remove (s = s.length = = 4) |
Returns the list of elements (returned list ("until") that were sorted after the element with length 4 in the thrill list was removed |
Thrill.reverse |
Returns a list of the reverse elements that contain the thrill list (return list ("Until", "fill", "would") |
Thrill.sort (s, t) = S.charat (0). toLowerCase < T.charat (0). toLowerCase) |
Returns a list of all the elements that include the thrill list, and the first character in alphabetical order (Return to lists ("Fill", "until", "would") |
Thrill.tail |
Returns a list of thrill that removed the first element (return list ("Fill", "until")) |
Nineth Step: Using tuple
Another useful container object is the tuple: tuple. As with lists, tuples are immutable, but unlike lists, tuples can contain different types of elements. And the list should be list[int] or list[string], tuples can have both Int and String. Tuples are useful, for example, if you need to return multiple objects in a method. In Java you will often create a javabean-like class to load multiple return values, and in Scala you can simply return a single tuple. And it's really simple: instantiate a new tuple with some objects, just put them in parentheses and separate them with commas. Once you have instantiated a tuple, you can access it with a dot, an underscore, and a 1-based element index. Code 3.4 shows an example:
Val pair = ("luftballons") println (pair._1) println (pair._2)
The next step in Scala