Merge branch 'master' of github.com:adambard/learnxinyminutes-docs

This commit is contained in:
Ian Bertolacci 2015-08-05 18:26:24 -07:00
commit 171f179f6e
2 changed files with 86 additions and 86 deletions

View File

@ -5,6 +5,7 @@ contributors:
- ["George Petrov", "http://github.com/petrovg"] - ["George Petrov", "http://github.com/petrovg"]
- ["Dominic Bou-Samra", "http://dbousamra.github.com"] - ["Dominic Bou-Samra", "http://dbousamra.github.com"]
- ["Geoff Liu", "http://geoffliu.me"] - ["Geoff Liu", "http://geoffliu.me"]
- ["Ha-Duong Nguyen", "http://reference-error.org"]
filename: learn.scala filename: learn.scala
--- ---
@ -16,15 +17,16 @@ Scala - the scalable language
Set yourself up: Set yourself up:
1) Download Scala - http://www.scala-lang.org/downloads 1) Download Scala - http://www.scala-lang.org/downloads
2) unzip/untar in your favourite location and put the bin subdir on the path 2) Unzip/untar to your favourite location and put the bin subdir in your `PATH` environment variable
3) Start a scala REPL by typing scala. You should see the prompt: 3) Start a Scala REPL by running `scala`. You should see the prompt:
scala> scala>
This is the so called REPL (Read-Eval-Print Loop). You may type any valid This is the so called REPL (Read-Eval-Print Loop). You may type any Scala
Scala expression into it, and the result will be printed. We will explain what expression, and the result will be printed. We will explain what Scala files
Scala files look like further into this tutorial, but for now, let's start look like further into this tutorial, but for now, let's start with some
with some basics. basics.
*/ */
@ -32,10 +34,10 @@ Scala - the scalable language
// 1. Basics // 1. Basics
///////////////////////////////////////////////// /////////////////////////////////////////////////
// Single line comments start with two forward slashes // Single-line comments start with two forward slashes
/* /*
Multi line comments, as you can already see from above, look like this. Multi-line comments, as you can already see from above, look like this.
*/ */
// Printing, and forcing a new line on the next print // Printing, and forcing a new line on the next print
@ -46,12 +48,12 @@ println(10)
print("Hello world") print("Hello world")
// Declaring values is done using either var or val. // Declaring values is done using either var or val.
// val declarations are immutable, whereas var's are mutable. Immutability is // val declarations are immutable, whereas vars are mutable. Immutability is
// a good thing. // a good thing.
val x = 10 // x is now 10 val x = 10 // x is now 10
x = 20 // error: reassignment to val x = 20 // error: reassignment to val
var y = 10 var y = 10
y = 20 // y is now 20 y = 20 // y is now 20
/* /*
Scala is a statically typed language, yet note that in the above declarations, Scala is a statically typed language, yet note that in the above declarations,
@ -71,17 +73,17 @@ true
false false
// Boolean operations // Boolean operations
!true // false !true // false
!false // true !false // true
true == false // false true == false // false
10 > 5 // true 10 > 5 // true
// Math is as per usual // Math is as per usual
1 + 1 // 2 1 + 1 // 2
2 - 1 // 1 2 - 1 // 1
5 * 3 // 15 5 * 3 // 15
6 / 2 // 3 6 / 2 // 3
6 / 4 // 1 6 / 4 // 1
6.0 / 4 // 1.5 6.0 / 4 // 1.5
@ -120,12 +122,12 @@ s"We have $n apples" // => "We have 45 apples"
// Expressions inside interpolated strings are also possible // Expressions inside interpolated strings are also possible
val a = Array(11, 9, 6) val a = Array(11, 9, 6)
s"My second daughter is ${a(0) - a(2)} years old." // => "My second daughter is 5 years old." s"My second daughter is ${a(0) - a(2)} years old." // => "My second daughter is 5 years old."
s"We have double the amount of ${n / 2.0} in apples." // => "We have double the amount of 22.5 in apples." s"We have double the amount of ${n / 2.0} in apples." // => "We have double the amount of 22.5 in apples."
s"Power of 2: ${math.pow(2, 2)}" // => "Power of 2: 4" s"Power of 2: ${math.pow(2, 2)}" // => "Power of 2: 4"
// Formatting with interpolated strings with the prefix "f" // Formatting with interpolated strings with the prefix "f"
f"Power of 5: ${math.pow(5, 2)}%1.0f" // "Power of 5: 25" f"Power of 5: ${math.pow(5, 2)}%1.0f" // "Power of 5: 25"
f"Square root of 122: ${math.sqrt(122)}%1.4f" // "Square root of 122: 11.0454" f"Square root of 122: ${math.sqrt(122)}%1.4f" // "Square root of 122: 11.0454"
// Raw strings, ignoring special characters. // Raw strings, ignoring special characters.
@ -171,12 +173,12 @@ def sq(x: Int) = x * x // Compiler can guess return type is Int
// Functions can have default parameters: // Functions can have default parameters:
def addWithDefault(x: Int, y: Int = 5) = x + y def addWithDefault(x: Int, y: Int = 5) = x + y
addWithDefault(1, 2) // => 3 addWithDefault(1, 2) // => 3
addWithDefault(1) // => 6 addWithDefault(1) // => 6
// Anonymous functions look like this: // Anonymous functions look like this:
(x:Int) => x * x (x: Int) => x * x
// Unlike defs, even the input type of anonymous functions can be omitted if the // Unlike defs, even the input type of anonymous functions can be omitted if the
// context makes it clear. Notice the type "Int => Int" which means a function // context makes it clear. Notice the type "Int => Int" which means a function
@ -193,8 +195,8 @@ sq(10) // => 100
val addOne: Int => Int = _ + 1 val addOne: Int => Int = _ + 1
val weirdSum: (Int, Int) => Int = (_ * 2 + _ * 3) val weirdSum: (Int, Int) => Int = (_ * 2 + _ * 3)
addOne(5) // => 6 addOne(5) // => 6
weirdSum(2, 4) // => 16 weirdSum(2, 4) // => 16
// The return keyword exists in Scala, but it only returns from the inner-most // The return keyword exists in Scala, but it only returns from the inner-most
@ -204,9 +206,9 @@ weirdSum(2, 4) // => 16
def foo(x: Int): Int = { def foo(x: Int): Int = {
val anonFunc: Int => Int = { z => val anonFunc: Int => Int = { z =>
if (z > 5) if (z > 5)
return z // This line makes z the return value of foo! return z // This line makes z the return value of foo!
else else
z + 2 // This line is the return value of anonFunc z + 2 // This line is the return value of anonFunc
} }
anonFunc(x) // This line is the return value of foo anonFunc(x) // This line is the return value of foo
} }
@ -218,19 +220,19 @@ def foo(x: Int): Int = {
1 to 5 1 to 5
val r = 1 to 5 val r = 1 to 5
r.foreach( println ) r.foreach(println)
r foreach println r foreach println
// NB: Scala is quite lenient when it comes to dots and brackets - study the // NB: Scala is quite lenient when it comes to dots and brackets - study the
// rules separately. This helps write DSLs and APIs that read like English // rules separately. This helps write DSLs and APIs that read like English
(5 to 1 by -1) foreach ( println ) (5 to 1 by -1) foreach (println)
// A while loops // A while loops
var i = 0 var i = 0
while (i < 10) { println("i " + i); i+=1 } while (i < 10) { println("i " + i); i += 1 }
while (i < 10) { println("i " + i); i+=1 } // Yes, again. What happened? Why? while (i < 10) { println("i " + i); i += 1 } // Yes, again. What happened? Why?
i // Show the value of i. Note that while is a loop in the classical sense - i // Show the value of i. Note that while is a loop in the classical sense -
// it executes sequentially while changing the loop variable. while is very // it executes sequentially while changing the loop variable. while is very
@ -239,19 +241,19 @@ i // Show the value of i. Note that while is a loop in the classical sense -
// A do while loop // A do while loop
do { do {
println("x is still less than 10"); println("x is still less than 10")
x += 1 x += 1
} while (x < 10) } while (x < 10)
// Tail recursion is an idiomatic way of doing recurring things in Scala. // Tail recursion is an idiomatic way of doing recurring things in Scala.
// Recursive functions need an explicit return type, the compiler can't infer it. // Recursive functions need an explicit return type, the compiler can't infer it.
// Here it's Unit. // Here it's Unit.
def showNumbersInRange(a:Int, b:Int):Unit = { def showNumbersInRange(a: Int, b: Int): Unit = {
print(a) print(a)
if (a < b) if (a < b)
showNumbersInRange(a + 1, b) showNumbersInRange(a + 1, b)
} }
showNumbersInRange(1,14) showNumbersInRange(1, 14)
// Conditionals // Conditionals
@ -305,13 +307,13 @@ s(1)
(a, 2, "three") (a, 2, "three")
// Why have this? // Why have this?
val divideInts = (x:Int, y:Int) => (x / y, x % y) val divideInts = (x: Int, y: Int) => (x / y, x % y)
divideInts(10,3) // The function divideInts gives you the result and the remainder divideInts(10, 3) // The function divideInts gives you the result and the remainder
// To access the elements of a tuple, use _._n where n is the 1-based index of // To access the elements of a tuple, use _._n where n is the 1-based index of
// the element // the element
val d = divideInts(10,3) val d = divideInts(10, 3)
d._1 d._1
@ -359,7 +361,7 @@ class Dog(br: String) {
val mydog = new Dog("greyhound") val mydog = new Dog("greyhound")
println(mydog.breed) // => "greyhound" println(mydog.breed) // => "greyhound"
println(mydog.bark) // => "Woof, woof!" println(mydog.bark) // => "Woof, woof!"
// The "object" keyword creates a type AND a singleton instance of it. It is // The "object" keyword creates a type AND a singleton instance of it. It is
@ -414,8 +416,8 @@ val otherGeorge = george.copy(phoneNumber = "9876")
def matchPerson(person: Person): String = person match { def matchPerson(person: Person): String = person match {
// Then you specify the patterns: // Then you specify the patterns:
case Person("George", number) => "We found George! His number is " + number case Person("George", number) => "We found George! His number is " + number
case Person("Kate", number) => "We found Kate! Her number is " + number case Person("Kate", number) => "We found Kate! Her number is " + number
case Person(name, number) => "We matched someone : " + name + ", phone : " + number case Person(name, number) => "We matched someone : " + name + ", phone : " + number
} }
val email = "(.*)@(.*)".r // Define a regex for the next example. val email = "(.*)@(.*)".r // Define a regex for the next example.
@ -446,7 +448,7 @@ def matchEverything(obj: Any): String = obj match {
case List(1, b, c) => s"Got a list with three elements and starts with 1: 1, $b, $c" case List(1, b, c) => s"Got a list with three elements and starts with 1: 1, $b, $c"
// You can nest patterns: // You can nest patterns:
case List(List((1, 2,"YAY"))) => "Got a list of list of tuple" case List(List((1, 2, "YAY"))) => "Got a list of list of tuple"
} }
// In fact, you can pattern match any object with an "unapply" method. This // In fact, you can pattern match any object with an "unapply" method. This
@ -493,7 +495,7 @@ sSquared.reduce (_+_)
// The filter function takes a predicate (a function from A -> Boolean) and // The filter function takes a predicate (a function from A -> Boolean) and
// selects all elements which satisfy the predicate // selects all elements which satisfy the predicate
List(1, 2, 3) filter (_ > 2) // List(3) List(1, 2, 3) filter (_ > 2) // List(3)
case class Person(name:String, age:Int) case class Person(name: String, age: Int)
List( List(
Person(name = "Dom", age = 23), Person(name = "Dom", age = 23),
Person(name = "Bob", age = 30) Person(name = "Bob", age = 30)
@ -541,8 +543,8 @@ implicit def myImplicitFunction(breed: String) = new Dog("Golden " + breed)
// By itself, implicit keyword doesn't change the behavior of the value, so // By itself, implicit keyword doesn't change the behavior of the value, so
// above values can be used as usual. // above values can be used as usual.
myImplicitInt + 2 // => 102 myImplicitInt + 2 // => 102
myImplicitFunction("Pitbull").breed // => "Golden Pitbull" myImplicitFunction("Pitbull").breed // => "Golden Pitbull"
// The difference is that these values are now eligible to be used when another // The difference is that these values are now eligible to be used when another
// piece of code "needs" an implicit value. One such situation is implicit // piece of code "needs" an implicit value. One such situation is implicit
@ -570,8 +572,8 @@ def foo[T : C] = ...
// implicit conversion of type A => B, where A is the type of obj, and B has a // implicit conversion of type A => B, where A is the type of obj, and B has a
// method called "method", that conversion is applied. So having // method called "method", that conversion is applied. So having
// myImplicitFunction above in scope, we can say: // myImplicitFunction above in scope, we can say:
"Retriever".breed // => "Golden Retriever" "Retriever".breed // => "Golden Retriever"
"Sheperd".bark // => "Woof, woof!" "Sheperd".bark // => "Woof, woof!"
// Here the String is first converted to Dog using our function above, and then // Here the String is first converted to Dog using our function above, and then
// the appropriate method is called. This is an extremely powerful feature, but // the appropriate method is called. This is an extremely powerful feature, but
@ -594,7 +596,7 @@ import scala.collection.immutable._
import scala.collection.immutable.{List, Map} import scala.collection.immutable.{List, Map}
// Rename an import using '=>' // Rename an import using '=>'
import scala.collection.immutable.{ List => ImmutableList } import scala.collection.immutable.{List => ImmutableList}
// Import all classes, except some. The following excludes Map and Set: // Import all classes, except some. The following excludes Map and Set:
import scala.collection.immutable.{Map => _, Set => _, _} import scala.collection.immutable.{Map => _, Set => _, _}
@ -629,13 +631,8 @@ writer.close()
## Further resources ## Further resources
[Scala for the impatient](http://horstmann.com/scala/) * [Scala for the impatient](http://horstmann.com/scala/)
* [Twitter Scala school](http://twitter.github.io/scala_school/)
[Twitter Scala school](http://twitter.github.io/scala_school/) * [The scala documentation](http://docs.scala-lang.org/)
* [Try Scala in your browser](http://scalatutorials.com/tour/)
[The scala documentation](http://docs.scala-lang.org/) * Join the [Scala user group](https://groups.google.com/forum/#!forum/scala-user)
[Try Scala in your browser](http://scalatutorials.com/tour/)
Join the [Scala user group](https://groups.google.com/forum/#!forum/scala-user)

View File

@ -4,6 +4,7 @@ contributors:
- ["Grant Timmerman", "http://github.com/grant"] - ["Grant Timmerman", "http://github.com/grant"]
- ["Christopher Bess", "http://github.com/cbess"] - ["Christopher Bess", "http://github.com/cbess"]
- ["Joey Huang", "http://github.com/kamidox"] - ["Joey Huang", "http://github.com/kamidox"]
- ["Anthony Nguyen", "http://github.com/anthonyn60"]
filename: learnswift.swift filename: learnswift.swift
--- ---
@ -26,7 +27,9 @@ import UIKit
// TODO: Do something soon // TODO: Do something soon
// FIXME: Fix this code // FIXME: Fix this code
println("Hello, world") // In Swift 2, println and print were combined into one print method. Print automatically appends a new line.
print("Hello, world") // println is now print
print("Hello, world", appendNewLine: false) // printing without appending a newline
// variables (var) value can change after being set // variables (var) value can change after being set
// constants (let) value can NOT be changed after being set // constants (let) value can NOT be changed after being set
@ -46,12 +49,12 @@ let piText = "Pi = \(π), Pi 2 = \(π * 2)" // String interpolation
// Build Specific values // Build Specific values
// uses -D build configuration // uses -D build configuration
#if false #if false
println("Not printed") print("Not printed")
let buildValue = 3 let buildValue = 3
#else #else
let buildValue = 7 let buildValue = 7
#endif #endif
println("Build value: \(buildValue)") // Build value: 7 print("Build value: \(buildValue)") // Build value: 7
/* /*
Optionals are a Swift language feature that allows you to store a `Some` or Optionals are a Swift language feature that allows you to store a `Some` or
@ -69,7 +72,7 @@ var someOptionalString2: Optional<String> = "optional"
if someOptionalString != nil { if someOptionalString != nil {
// I am not nil // I am not nil
if someOptionalString!.hasPrefix("opt") { if someOptionalString!.hasPrefix("opt") {
println("has the prefix") print("has the prefix")
} }
let empty = someOptionalString?.isEmpty let empty = someOptionalString?.isEmpty
@ -138,21 +141,21 @@ var emptyMutableDictionary = [String: Float]() // var == mutable
let myArray = [1, 1, 2, 3, 5] let myArray = [1, 1, 2, 3, 5]
for value in myArray { for value in myArray {
if value == 1 { if value == 1 {
println("One!") print("One!")
} else { } else {
println("Not one!") print("Not one!")
} }
} }
// for loop (dictionary) // for loop (dictionary)
var dict = ["one": 1, "two": 2] var dict = ["one": 1, "two": 2]
for (key, value) in dict { for (key, value) in dict {
println("\(key): \(value)") print("\(key): \(value)")
} }
// for loop (range) // for loop (range)
for i in -1...shoppingList.count { for i in -1...shoppingList.count {
println(i) print(i)
} }
shoppingList[1...2] = ["steak", "peacons"] shoppingList[1...2] = ["steak", "peacons"]
// use ..< to exclude the last number // use ..< to exclude the last number
@ -165,7 +168,7 @@ while i < 1000 {
// do-while loop // do-while loop
do { do {
println("hello") print("hello")
} while 1 == 2 } while 1 == 2
// Switch // Switch
@ -222,8 +225,8 @@ let pricesTuple = getGasPrices()
let price = pricesTuple.2 // 3.79 let price = pricesTuple.2 // 3.79
// Ignore Tuple (or other) values by using _ (underscore) // Ignore Tuple (or other) values by using _ (underscore)
let (_, price1, _) = pricesTuple // price1 == 3.69 let (_, price1, _) = pricesTuple // price1 == 3.69
println(price1 == pricesTuple.1) // true print(price1 == pricesTuple.1) // true
println("Gas price: \(price)") print("Gas price: \(price)")
// Variadic Args // Variadic Args
func setup(numbers: Int...) { func setup(numbers: Int...) {
@ -251,7 +254,7 @@ func swapTwoInts(inout a: Int, inout b: Int) {
var someIntA = 7 var someIntA = 7
var someIntB = 3 var someIntB = 3
swapTwoInts(&someIntA, &someIntB) swapTwoInts(&someIntA, &someIntB)
println(someIntB) // 7 print(someIntB) // 7
// //
@ -305,7 +308,7 @@ struct NamesTable {
// Structures have an auto-generated (implicit) designated initializer // Structures have an auto-generated (implicit) designated initializer
let namesTable = NamesTable(names: ["Me", "Them"]) let namesTable = NamesTable(names: ["Me", "Them"])
let name = namesTable[1] let name = namesTable[1]
println("Name is \(name)") // Name is Them print("Name is \(name)") // Name is Them
// //
// MARK: Classes // MARK: Classes
@ -386,7 +389,7 @@ let aShape = mySquare as Shape
// compare instances, not the same as == which compares objects (equal to) // compare instances, not the same as == which compares objects (equal to)
if mySquare === mySquare { if mySquare === mySquare {
println("Yep, it's mySquare") print("Yep, it's mySquare")
} }
// Optional init // Optional init
@ -409,13 +412,13 @@ class Circle: Shape {
} }
var myCircle = Circle(radius: 1) var myCircle = Circle(radius: 1)
println(myCircle?.getArea()) // Optional(3) print(myCircle?.getArea()) // Optional(3)
println(myCircle!.getArea()) // 3 print(myCircle!.getArea()) // 3
var myEmptyCircle = Circle(radius: -1) var myEmptyCircle = Circle(radius: -1)
println(myEmptyCircle?.getArea()) // "nil" print(myEmptyCircle?.getArea()) // "nil"
if let circle = myEmptyCircle { if let circle = myEmptyCircle {
// will not execute since myEmptyCircle is nil // will not execute since myEmptyCircle is nil
println("circle is not nil") print("circle is not nil")
} }
@ -447,7 +450,7 @@ enum BookName: String {
case John = "John" case John = "John"
case Luke = "Luke" case Luke = "Luke"
} }
println("Name: \(BookName.John.rawValue)") print("Name: \(BookName.John.rawValue)")
// Enum with associated Values // Enum with associated Values
enum Furniture { enum Furniture {
@ -467,9 +470,9 @@ enum Furniture {
} }
var desk: Furniture = .Desk(height: 80) var desk: Furniture = .Desk(height: 80)
println(desk.description()) // "Desk with 80 cm" print(desk.description()) // "Desk with 80 cm"
var chair = Furniture.Chair("Foo", 40) var chair = Furniture.Chair("Foo", 40)
println(chair.description()) // "Chair of Foo with 40 cm" print(chair.description()) // "Chair of Foo with 40 cm"
// //
@ -522,7 +525,7 @@ extension Square: Printable {
} }
} }
println("Square: \(mySquare)") print("Square: \(mySquare)")
// You can also extend built-in types // You can also extend built-in types
extension Int { extension Int {
@ -535,8 +538,8 @@ extension Int {
} }
} }
println(7.customProperty) // "This is 7" print(7.customProperty) // "This is 7"
println(14.multiplyBy(3)) // 42 print(14.multiplyBy(3)) // 42
// Generics: Similar to Java and C#. Use the `where` keyword to specify the // Generics: Similar to Java and C#. Use the `where` keyword to specify the
// requirements of the generics. // requirements of the generics.
@ -550,7 +553,7 @@ func findIndex<T: Equatable>(array: [T], valueToFind: T) -> Int? {
return nil return nil
} }
let foundAtIndex = findIndex([1, 2, 3, 4], 3) let foundAtIndex = findIndex([1, 2, 3, 4], 3)
println(foundAtIndex == 2) // true print(foundAtIndex == 2) // true
// Operators: // Operators:
// Custom operators can start with the characters: // Custom operators can start with the characters:
@ -566,9 +569,9 @@ prefix func !!! (inout shape: Square) -> Square {
} }
// current value // current value
println(mySquare.sideLength) // 4 print(mySquare.sideLength) // 4
// change side length using custom !!! operator, increases size by 3 // change side length using custom !!! operator, increases size by 3
!!!mySquare !!!mySquare
println(mySquare.sideLength) // 12 print(mySquare.sideLength) // 12
``` ```