conditional evaluation
compound expression,將一連串的 code 合併起來,確保會依照順序運算,除了換行的方式,還可以用 ; 區隔,寫在同一行
julia> volume = begin
len = 10
breadth = 20
height = 30
len * breadth * height
end
6000
julia> volume = (length = 10; breadth = 20; height = 30; length * breadth * height)
6000
conditional evaluation
FizzBuzz algorithm,用 if, elseif, else 撰寫條件
for i in 1:30
if i % 3 == 0 && i % 5 == 0
println("FizzBuzz")
elseif i % 3 == 0
println("Fizz")
elseif i % 5 == 0
println("Buzz")
else
println(i)
end
end
計算是否為質數的 function
function factors(num::Int64)
factors = []
for i in 1:num
if rem(num, i) == 0
push!(factors, i)
end
end
return factors
end
function is_prime(num::Int64)
factors_array = factors(num)
if length(factors_array) == 2
true
else
false
end
end
if 區塊裡面的變數,在區塊外面還可以使用,這表示 if block 並沒有 local scope
function f(n)
if n % 2 == 0
parity = "even"
else
parity = "odd"
end
println("the number is $parity")
end
if block 結束時,會 return value
julia> x = if true
2
end
2
julia> x = if true
println("test")
end
test
julia> x == nothing
true
ternary operators
condition ? do this, if true : do this, if false
julia> name = "julia"
"julia"
julia> isa(name, String) ? "its a string" : "nopes, not a string"
"its a string"
short circuit evalation
- var1 && var2,只有在 var1 為 true,才會運算 var2
- var1 || var2,當 var1 為 false,才會運算 var2
julia> all(isdigit, "10") && println("reached me")
reached me
julia> all(isdigit, "ten") && println("reached me")
false
julia> all(isdigit, "ten") || println("reached me")
reached me
repeated evaluation
有兩種: while, for
collection = [1,2,3,4,5,6,7,8,9]
while length(collection) > 1
pop!(collection)
println(collection)
end
for
statement = "This is a great example!"
for word in split(statement)
println(word)
end
# split 後,取第 2~4 個元素
for word in split(statement)[2:4]
println(word)
end
for word in split(statement)[2:3:4]
println(word)
end
# is
defining range
range expression 1:5
julia> for i in 1:5
print("*",i,"\n", "\t"^i)
end
*1
*2
*3
*4
*5
5:-1:1
表示為 5 到 1,每一次 減1
julia> for i in 1:5
for j in 1:i
print("*")
end
println("")
end
*
**
***
****
*****
julia> for i in 5:-1:1
for j in 1:i
print("*")
end
println("")
end
*****
****
***
**
*
reverse a string
julia> my_string = "This is a great thing to do!"
"This is a great thing to do!"
julia> my_string[length(my_string):-1:1]
"!od ot gniht taerg a si sihT"
break and continue
word="julia"
for letter in word
if letter == 'i'
break
end
println(letter)
end
# continue 跳過此次迴圈,繼續下一個
for letter in word
if letter == 'l'
continue
end
println(letter)
end
Exception handling
error 跟 exception 的差異
error 是應該要避免的問題,程式不應該 catch error。程式已經知道可能會發生 exception,故在發生 exception 的條件中,可以 catch exception。
julia 提供多種 errors:
- ArgumentError: 傳入 function 的參數,不是原本 function 期待的參數形式
- AssertionError: 發生錯誤 (false) 的 assertion 檢查 statement
- BoundsError: 嘗試存取 arrary 的 out-of-bounds element
- DivideError: 除數為 0
- DomainError: 參數在 valid domain 之外
- EOFError: 已經到了 end of file,無法再讀取資料
- InexactError: 再處理 exact type conversion 發生 failure
- KeyError: 存取不存在的 key element
- LoadError: loading file 發生 error
- MethodError: 嘗試使用不存在的 methods
- OutOfMemoryError: 記憶體不足
- ReadOnlyMemoryError: 嘗試寫入 read-only memory
- OverflowError: 當某個 operation 的 result 太大
- ParseError: parsing expression 發生問題
- StackOverflowError: function call 超過 call stack
- SystemError: system call 發生 error
- TypeError: type checking 發生 error, 傳給 function 錯誤資料型別的參數
- UndefRefError: Unknown reference made
- UndefVarError: Unknown reference made to a 不存在的 variable
- InitError: 呼叫 module 的
__init__
發生錯誤
julia 的 exception
- ErrorException: 發生 error
- InterruptException: 運算時發生 external interruption
- NullException: 嘗試存取 Null
- ProcessExitedException: process 已結束,使用 process 就會發生錯誤
julia> typeof(Exception)
DataType
julia> struct CustomException <: Exception
var::Symbol
end
julia> typeof(CustomException)
DataType
julia> supertype(CustomException)
Exception
throw(e)
呼叫時,會立即 throws an error
julia> throw("")
ERROR: ""
Stacktrace:
[1] top-level scope at none:0
julia> throw(3+3)
ERROR: 6
Stacktrace:
[1] top-level scope at none:0
julia> throw(ErrorException("error"))
ERROR: error
Stacktrace:
[1] top-level scope at none:0
產生 TypeError
julia> function say_hi(name)
try
if typeof(name) != String
throw(TypeError(:say_hi, "printing name", String, name))
else
println("hi $name")
end
catch e
println(typeof(e))
end
end
say_hi (generic function with 1 method)
julia> say_hi('n')
TypeError
julia> say_hi("name")
hi name
error()
會產生 ErrorException
julia> function say_hi(name :: String)
if length(name) < 5
error("Name less than 5!!!")
else
println("hi $name")
end
end
say_hi (generic function with 2 methods)
julia> say_hi("joe")
ERROR: Name less than 5!!!
Stacktrace:
[1] error(::String) at ./error.jl:33
[2] say_hi(::String) at ./REPL[59]:3
[3] top-level scope at none:0
try/catch/finally block
用 try-catch block 封裝程式碼,攔截任何可能發生的 error
julia> try
exponent("alpha")
catch e
println(e)
finally
print("Goodbye")
end
MethodError(exponent, ("alpha",), 0x00000000000061d2)
Goodbye
tasks in julia
Tasks 類似 coroutines 的功能,可 suspend an operation 並在需要時 resume
julia> function producer(c::Channel)
put!(c, "start")
for n=1:2
put!(c, 2n)
end
put!(c, "stop")
end;
julia> chnl = Channel(producer);
julia> take!(chnl)
"start"
julia> take!(chnl)
2
julia> take!(chnl)
4
julia> take!(chnl)
"stop"
julia> take!(chnl)
ERROR: InvalidStateException("Channel is closed.", :closed)
Swift Enum 簡介
Swift語言的Enum使用方式,與C++,Java等常見的程式語言無太大差異,範例如下:
Associated value
而Associated value則是Swift語言的Enum中,比較特別的一個功能。你可以讓一個enum變數額外地儲存多個其他的值,且幾乎可以是任意型別。
舉例來說,我想要讓cloudItem儲存一個代表網址的字串;而localItem則儲存了一個代表檔案路徑的字串,以及代表檔案大小的Int數值:
在switch case中取得associated value
在使用switch case判斷enum變數的類型時,
可在後面加上括號,並寫上let或var以及變數名稱,
以取出associated value,範例如下:
在switch case以外的場合取得associated value
使用if
若只想要針對特定的enum取出associated value,也可以改使用if case
if case的let/var可提到前面:
if case的後面,可加上逗號,並於逗號後面做額外的條件判斷:
使用for
除了if case之外,還有for迴圈也可以取得associated value,範例如下
for case可使用where加上條件判斷
使用guard
同樣屬於條件判斷類型的guard,也可以使用case取得associated value並做判斷
Recursive Enumerations
由於associated value可以是任何型態的變數,因此也可以是自身型態的enum,進而形成了Recursive Enumerations
要特別注意的是,associated value中用到的變數型態有自身的enum的話,要加上indirect
indirect也可以加在自身的enum宣告前面,這樣即可不用在每個有使用到associated value的項目中再寫一次
Reference
Enumeration - The Swift Programming Language (Swift 5)
Pattern Matching, Part 4: if case, guard case, for case- Crunchy Development