如何讓你的程式不失控呢?當然就是要學好控制流程啦!今天我們來談談 Conditional statements,也就是如何改變程式執行的流程。其實就是像 if , switch , while 等等之類的唷!
給一個整數 n, 如果是奇數或者是 6~20 之間的偶數就說他是 Weird,反之就是 Not Weird。
那就讓我們看看各語言有什麼名堂吧!
import scala.io.StdIn._
object Solution {
def main(args: Array[String]) {
val n = readInt
n % 2 match {
case 0 => n match {
case x if (1 < x && x < 6) || x > 20 => println("Not Weird")
case _ => println ("Weird")
}
case _ => println("Weird")
}
}
}
if-else
來去做判斷。但是在 Scala 裡面,有個更厲害的東西叫做 Pattern matching,我們先前在 Rust 也有稍微提過。Pattern matching 除了達到像 Switch 的效果,還能幫助我們去解析出被 Match 的 Object 的一些屬性 (之後會再提到),甚至是可以幫助我們判斷型別等等。在這裡我們透過 match
來做到像是 Switch 的功能,判斷 n % 2
會是什麼樣的 "Pattern" 並且做後續邏輯處理。而 n % 2
我們知道不是 0
就是 1
,而這裡主要需要處理的是等於 0
的情況,也就是 n
是偶數。match
一定會跟著很多的 case
,也就是 Patterns。這裡我們有個巢狀的 match
。先來看最外層的 match
有兩個 case: case 0
, case _
。 case 0
表示當 n % 2
等於 0
時,就做後面的事 ( =>
後面的邏輯),而 case _
是處理 Default 的行為,也就是當上面的 Case 都不成立時所使用。match
,這裡是要判斷 n
是否介於 1~6 以及大於 12,第一個 case 表示假設 x
是 n
,且 x
在 if
後面的判斷成立,就做 =>
後面的事情。這時候的 if
又叫做 Pattern guard,也就是讓我們再加上對於是否吻合 Pattern 的判斷。x
在某個條件下是 1
,其他則是 2
時,我們可以這樣寫 val x = if (...) 1 else 2
,為什麼?因為我們說過 Scala 本身也是個 expression based 的語言,if (...) 1 else 2
這個表達式最後會被計算而產生一個值,所以當然就可以拿來賦予給 x
囉!更深入的 Pattern matching 可參考這裡。A && B
或 A || B
如果已經可以從 A
知道整個結果是 false/true,那後者( B
)就不會再被執行了。n = int(input())
result = 'Weird'
if n % 2 == 0 and not n in range(6, 21):
result = 'Not ' + result
print(result)
n
是偶數 (n % 2
等於 0) 且 n
不在 6~20 話就印出 Not Weird
,反之則是 Weird
。因為 Python 的部分滿簡單的,我們就來看看幾個比較特別的地方。if
是沒有括號的,而且 Code block 一樣是靠縮排。其他的語言在做 And/Or 的判斷時,通常會寫成像是 &&
跟 ||
,但在 Python 的世界,用比較口語的方式,像是這裡的 and
, not
或是 or
,其中 not
就是反向的意思。 not n in range(6, 21)
,就是說 n
不在 range(6, 21)
,而 range(6, 21)
代表的是 6~20 唷 (不是 21), range(start, stop, step)
是 Python 內建的函數,可以產生數字序列, start
是起始點, stop
是終點,而 step
表示一次跳多少個數字。range
常被用在 loop 結構中,當我們需要去執行多次動作的時候,可以利用 range
產生的數字序列來代表執行的次數。我相信之後我們就會再跟他見面了。A and B
如果 A
是 false
,那麼 B
就不會被執行了,因為已經可以確定整個結果一定是 false
;反之, A or B
,如果 A
是 true
,那麼 B
也不會被執行了。package main
import (
"fmt"
"os"
"bufio"
"strconv"
)
func main() {
scanner := bufio.NewScanner(os.Stdin)
scanner.Scan()
n, _ := strconv.ParseInt(scanner.Text(), 10, 64)
if n % 2 != 0 {
fmt.Println("Weird")
} else {
switch {
case (6 <= n) && (n <= 20): fmt.Println("Weird")
default: fmt.Println("Not Weird")
}
}
}
if
搭配 switch
。Golang 的 if
一樣不用括號。而 Golang 的 switch
就不是 Pattern matching 了,而是一般的 switch ,也是就看值是多少,找到對應的 case 然後執行程式 (可參考這裡)。如果都沒有對應的 case 就執行 default 的內容。而這裡比較特別的是,我們不是 switch xxx {}
,而是把判斷邏輯也寫在 case 裡頭: case (6 <= n) && (n <= 20)
。switch t := x.(type) {
case bool:
fmt.Println("I'm a bool")
case int:
fmt.Println("I'm an int")
default:
fmt.Printf("Don't know type %T\n", t)
}
use std::io;
fn main () {
let mut input = String::new();
io::stdin().read_line(&mut input)
.expect("Error reading input");
let n :i32 = match input.trim().parse() {
Ok(num) => num,
Err(_) => 0,
};
match n {
x if x % 2 != 0 => println!("Weird"),
6 ... 20 => println!("Weird"),
_ => println!("Not Weird")
}
}
match
之後,也就是 n
,再來下一行是說,假設 x
是 n
,如果 x % 2 != 0
表示這個 Pattern 有 Match 到,所以就執行 =>
後面的內容。這裡的 if
在 Rust 也是稱作 Guard。比較酷的是下一行,Rust 可以讓我們 Match 一個 Range,在這裡 6 ... 20
表示 6 到 20 (有包含 20 唷!)。除此之外還有像是可以 Match 像是'a' ... 'j'
表示 a~j 的字母。而最後的 是 Default Pattern。今天的內容似乎比較簡單,不過下一章應該就精彩了!我們要來談談 Class 和 Struct 囉!明天見!