####################################################
## 3. 控制流
####################################################
# 宣告一個變數
some_var = 5
# 這是一個 if 語句,縮排不是必要的
if some_var > 10
println("some_var is totally bigger than 10.")
elseif some_var < 10 # elseif 是可選的.
println("some_var is smaller than 10.")
else # else 也是可選的.
println("some_var is indeed 10.")
end
# => prints "some var is smaller than 10"
# For 迴圈遍歷
# Iterable 型別包括 Range, Array, Set, Dict, 以及 String.
for animal=["dog", "cat", "mouse"]
println("$animal is a mammal")
# 可用 $ 將 variables 或 expression 轉換為字串into strings
end
# prints:
# dog is a mammal
# cat is a mammal
# mouse is a mammal
# You can use 'in' instead of '='.
for animal in ["dog", "cat", "mouse"]
println("$animal is a mammal")
end
# prints:
# dog is a mammal
# cat is a mammal
# mouse is a mammal
for a in ["dog"=>"mammal","cat"=>"mammal","mouse"=>"mammal"]
println("$(a[1]) is a $(a[2])")
end
# prints:
# dog is a mammal
# cat is a mammal
# mouse is a mammal
for (k,v) in ["dog"=>"mammal","cat"=>"mammal","mouse"=>"mammal"]
println("$k is a $v")
end
# prints:
# dog is a mammal
# cat is a mammal
# mouse is a mammal
# While 迴圈
x = 0
while x < 4
println(x)
x += 1 # x = x + 1
end
# prints:
# 0
# 1
# 2
# 3
# 用 try/catch 處理異常
try
error("help")
catch e
println("caught it $e")
end
# => caught it ErrorException("help")
####################################################
## 4. 函式
####################################################
# 用關鍵字 'function' 可建立一個新函式
#function name(arglist)
# body...
#end
function add(x, y)
println("x is $x and y is $y")
# 最後一行語句的值為返回
x + y
end
add(5, 6) # => 在 "x is 5 and y is 6" 後會列印 11
# 還可以定義接收可變長引數的函式
function varargs(args...)
return args
# 關鍵字 return 可在函式內部任何地方返回
end
# => varargs (generic function with 1 method)
varargs(1,2,3) # => (1,2,3)
# 省略號 ... 被稱為 splat.
# 剛剛用在了函式定義中
# 還可以用在函式的呼叫
# Array 或者 Tuple 的內容會變成引數列表
Set([1,2,3]) # => Set{Array{Int64,1}}([1,2,3]) # 獲得一個 Array 的 Set
Set([1,2,3]...) # => Set{Int64}(1,2,3) # 相當於 Set(1,2,3)
x = (1,2,3) # => (1,2,3)
Set(x) # => Set{(Int64,Int64,Int64)}((1,2,3)) # 一個 Tuple 的 Set
Set(x...) # => Set{Int64}(2,3,1)
# 可定義可選引數的函式
function defaults(a,b,x=5,y=6)
return "$a $b and $x $y"
end
defaults('h','g') # => "h g and 5 6"
defaults('h','g','j') # => "h g and j 6"
defaults('h','g','j','k') # => "h g and j k"
try
defaults('h') # => ERROR: no method defaults(Char,)
defaults() # => ERROR: no methods defaults()
catch e
println(e)
end
# 還可以定義鍵值對的引數
function keyword_args(;k1=4,name2="hello") # note the ;
return ["k1"=>k1,"name2"=>name2]
end
keyword_args(name2="ness") # => ["name2"=>"ness","k1"=>4]
keyword_args(k1="mine") # => ["k1"=>"mine","name2"=>"hello"]
keyword_args() # => ["name2"=>"hello","k1"=>4]
# 可以組合各種型別的引數在同一個函式的引數列表中
function all_the_args(normal_arg, optional_positional_arg=2; keyword_arg="foo")
println("normal arg: $normal_arg")
println("optional arg: $optional_positional_arg")
println("keyword arg: $keyword_arg")
end
all_the_args(1, 3, keyword_arg=4)
# prints:
# normal arg: 1
# optional arg: 3
# keyword arg: 4
# Julia 有一等函式
function create_adder(x)
adder = function (y)
return x + y
end
return adder
end
# 這是用 "stabby lambda syntax" 建立的匿名函式
(x -> x > 2)(3) # => true
# 這個函式和上面的 create_adder 一模一樣
function create_adder(x)
y -> x + y
end
# 你也可以給內部函式起個名字
function create_adder(x)
function adder(y)
x + y
end
adder
end
add_10 = create_adder(10)
add_10(3) # => 13
# 內建的高階函式有
map(add_10, [1,2,3]) # => [11, 12, 13]
filter(x -> x > 5, [3, 4, 5, 6, 7]) # => [6, 7]
# 還可以使用 list comprehensions 替代 map
[add_10(i) for i=[1, 2, 3]] # => [11, 12, 13]
[add_10(i) for i in [1, 2, 3]] # => [11, 12, 13]
####################################################
## 5. 型別
####################################################
# Julia 有型別系統
# 所有的值都有型別;但變數本身沒有型別
# 你可以用 `typeof` 函式獲得值的型別
typeof(5) # => Int64
# 型別是一等值
typeof(Int64) # => DataType
typeof(DataType) # => DataType
# DataType 是代表型別的型別,也代表他自己的型別
# 型別可用作文件化,優化,以及排程
# 並不是靜態檢查型別
# 使用者還可以自定義型別
# 跟其他語言的 records 或 structs 一樣
# 用 `type` 關鍵字定義新的型別
# type Name
# field::OptionalType
# ...
# end
type Tiger
taillength::Float64
coatcolor # 不附帶型別標註的相當於 `::Any`
end
# 建構函式引數是型別的屬性
tigger = Tiger(3.5,"orange") # => Tiger(3.5,"orange")
# 用新型別作為建構函式還會建立一個型別
sherekhan = typeof(tigger)(5.6,"fire") # => Tiger(5.6,"fire")
# struct 類似的型別被稱為具體型別
# 他們可被例項化但不能有子型別
# 另一種型別是抽象型別
# abstract Name
abstract Cat # just a name and point in the type hierarchy
# 抽象型別不能被例項化,但是可以有子型別
# 例如,Number 就是抽象型別
subtypes(Number) # => 6-element Array{Any,1}:
# Complex{Float16}
# Complex{Float32}
# Complex{Float64}
# Complex{T<:Real}
# ImaginaryUnit
# Real
subtypes(Cat) # => 0-element Array{Any,1}
# 所有的型別都有父型別; 可以用函式 `super` 得到父型別.
typeof(5) # => Int64
super(Int64) # => Signed
super(Signed) # => Real
super(Real) # => Number
super(Number) # => Any
super(super(Signed)) # => Number
super(Any) # => Any
# 所有這些型別,除了 Int64, 都是抽象型別.
# <: 是型別整合操作符
type Lion <: Cat # Lion 是 Cat 的子型別
mane_color
roar::String
end
# 可以繼續為你的型別定義建構函式
# 只需要定義一個同名的函式
# 並呼叫已有的建構函式設定一個固定引數
Lion(roar::String) = Lion("green",roar)
# 這是一個外部建構函式,因為他再型別定義之外
type Panther <: Cat # Panther 也是 Cat 的子型別
eye_color
Panther() = new("green")
# Panthers 只有這個建構函式,沒有預設建構函式
end
# 使用內建建構函式,如 Panther,可以讓你控制
# 如何構造型別的值
# 應該儘可能使用外部建構函式而不是內部建構函式