julia 同樣也有 type system 處理 Types, Data Types,可識別 integer, string, float, Boolean。
Type system
types 是什麼?
1
1.1
'j'
"julia"
這些資料都可以直接識別出差異,分別是 integer, float, char, string。但需要一個方法讓電腦能夠識別這些資料型別。
static type vs dynamic type
有兩種方法可告訴 interpreter 資料型別是什麼
static type: 直接標記出資料型別,例如 C, C++, Java
dynamic type: interpreter 在 runitme 自動判斷資料型別,例如 Perl, Python, Ruby。雖然不指定,但內部還是會將該資料,標記為某一個資料型別
julia 同時有 static type 及 dynamic type 的功能。如果使用 static type,會讓程式運作地比較快。
Type annotations
討論 type declaration 及 conversion
:: Int64
就是將變數定義為 Int64 這個資料型別
julia> function cube(number::Int64)
return number ^ 3
end
cube (generic function with 1 method)
julia> cube(3)
27
實際上 ::
是個 operator,也很類似 python 的 isinstance()
julia> 2::Int64
2
julia> 2::Float64
ERROR: TypeError: in typeassert, expected Float64, got Int64
- typeof(): type of data
- typemax(): 該 type 可支援的最大 value
- typemin(): 該 type 可支援的最小 value
- bitstring(): 二進位的位元字串
Integer type 會根據使用的機器不同,可能是 Int8, Int16, Int32, Int64, or Int128 其中一種
julia> typeof(1) Int64 julia> typemax(Int64) 9223372036854775807 julia> typemin(Int64) -9223372036854775808
Float type 在 64bits 機器,是 Float64
julia> typeof(1.1) Float64 julia> typemax(Float64) Inf julia> typemin(Float64) -Inf
Char type
String type
Bool type
isa(x, type) -> Bool
判斷 x 資料型別是否為 type
julia> isa(5, Int64)
true
julia> isa(5.5, Float64)
true
type conversions
convert(type, x)
可將 x 轉換資料型別為 type
julia> convert(Float64, 10)
10.0
julia> convert(Int64, 128.0)
128
julia> convert(Int64, 128.3)
ERROR: InexactError: Int64(Int64, 128.3)
Stacktrace:
[1] Type at ./float.jl:700 [inlined]
[2] convert(::Type{Int64}, ::Float64) at ./number.jl:7
[3] top-level scope at none:0
rounding: ceil, floor, round
julia> ceil(Int, 3.4)
4
julia> floor(Int, 3.4)
3
julia> round(Int, 3.4)
3
julia> round(Int, 3.6)
4
subtypes and supertypes
Number 是 Any 的 subtype,Any 是 Number 的 supertype
Any
|
---------------------------------------------
Number AbstractString
| |
---------------- |
Complex Real |
|
|
----------------------------------------------------------
| | | | |
UTF8String UTF16String DirectIndexString RepString RopeString
Any 是所有資料型別的起點
julia> supertype(Number)
Any
julia> supertype(Any)
Any
julia> typeof(Any)
DataType
julia> subtypes(Number)
2-element Array{Any,1}:
Complex
Real
recursive 找出所有子類別
julia> function check_all_subtypes(T, space=0)
println("\t" ^ space, T)
for t in subtypes(T)
if t!= Any
check_all_subtypes(t, space+1)
end
end
end
check_all_subtypes (generic function with 2 methods)
julia> check_all_subtypes(Number)
Number
Complex
Real
AbstractFloat
BigFloat
Float16
Float32
Float64
AbstractIrrational
Irrational
Integer
Bool
Signed
BigInt
Int128
Int16
Int32
Int64
Int8
Unsigned
UInt128
UInt16
UInt32
UInt64
UInt8
Rational
User-defined and composite data types
可自訂資料型別: use abstract|primitive type
, struct
, mutable struct
for type definitions
ref: crazy idea: change the type
keyword
julia> struct Person
name::String
age::Int64
end
julia> typeof(Person)
DataType
julia> a = Person("Name", 10)
Person("Name", 10)
julia> typeof(a)
Person
julia> a.name
"Name"
julia> a.name = "name2"
ERROR: type Person is immutable
檢查自訂資料型別的層級
julia> supertype(Person)
Any
julia> subtypes(Person)
0-element Array{Type,1}
julia> fieldnames(Person)
(:name, :age)
julia> typeof(:name)
Symbol
composite types
剛剛的 Person 資料無法修改,使用 mutable struct
就可以變成可修改的資料型別
julia> mutable struct Point
x :: Int64
y :: Int64
z :: Int64
end
julia> p = Point(1,2,3)
Point(1, 2, 3)
julia> p.x=10
10
julia> p
Point(10, 2, 3)
Inner constructor
剛剛的 struct,可在 constructor 中,增加資料的檢查,確認新的物件符合資料型別設計的條件
julia> struct Family
num_members :: Int64
members :: Array{String, 1}
# inner constructor in play
Family(num_members, members) = num_members != length(members) ? error("Mismatch!!") : new(num_members, members)
end
julia> f1 = Family(1, ["husband", "wife"])
ERROR: Mismatch!!
Stacktrace:
[1] error(::String) at ./error.jl:33
[2] Family(::Int64, ::Array{String,1}) at ./REPL[14]:6
[3] top-level scope at none:0
julia> f2 = Family(2, ["husband", "wife"])
Family(2, ["husband", "wife"])
Modules and interfaces
julia 的 namespaces,可讓我們建立 top-level global variable,但又不會在所有程式中互相衝突。
module SampleModule
..
..
end
julia> module MyModule
foo=10
bar=20
function baz()
"baz"
end
function qux()
"qux"
end
export foo, baz
end
Main.MyModule
julia> MyModule.bar
20
using MyModule 跟 import MyModule 的差異
- using MyModule,會將所有 exported functions 都帶入目前的 scope,等於是宣告 MyModule.foo,可以這樣使用 MyModule:foo
- import MyModule,將 functions 匯入目前的 scope,只能取得 exported functions/variables,就無法使用 foo
Including files in modules
當 module, package 分散在多個檔案中,使用 include
彙整
# 按下 ; 進入 shell
# transformations.jl 是獨立的檔案
shell> cat transformations.jl
function say_hello(name:: String)
"hello, $name"
end
julia> include("transformations.jl")
say_hello (generic function with 1 method)
julia> say_hello("rahul")
"hello, rahul"
Module file paths
通常用 using SomeModule 時,julia 會尋找預設 module 路徑
可用 push! 增加 library 路徑,或是設定環境變數 JULIA_LOAD_PATH
julia> push!(LOAD_PATH, "~/Downloads/Module/")
4-element Array{String,1}:
"@"
"@v#.#"
"@stdlib"
"~/Downloads/Module/"
module precompilation
在使用某個 module 時,會先花一些時間進行編譯,如果有編譯完成的,才會直接匯入
目前 1.0 版,所有 modules 都是enable precompilation
Samplecode.jl
module Samplecode
export sum_of_numbers
sum_of_numbers = 0
for num in 1:10000
global sum_of_numbers += num
end
end
julia> push!(LOAD_PATH, "~/path/")
4-element Array{String,1}:
"@"
"@v#.#"
"@stdlib"
"~/path/"
julia> @time using Samplecode
[ Info: Precompiling Samplecode [top-level]
1.343508 seconds (1.13 M allocations: 55.605 MiB, 0.38% gc time)
julia> @time using Samplecode
0.000552 seconds (782 allocations: 42.547 KiB)
multiple dispatch
julia> struct Coordinate{T}
x::T
y::T
z::T
end
julia> function calc_sum(value::Coordinate{Int64})
value.x + value.y + value.z
end
calc_sum (generic function with 1 method)
julia> function calc_sum(value::Coordinate{Float64})
value.x + value.y + value.z
end
calc_sum (generic function with 2 methods)
julia> methods(calc_sum)
# 2 methods for generic function "calc_sum":
[1] calc_sum(value::Coordinate{Float64}) in Main at REPL[6]:2
[2] calc_sum(value::Coordinate{Int64}) in Main at REPL[5]:2
julia> calc_sum(Coordinate(1,2,3))
6
julia> calc_sum(Coordinate(1.0,2.0,3.0))
6.0
沒有留言:
張貼留言