In [ ]:
#
# 나는 julia 를 사랑하는가
#
In [ ]:
# Types
In [ ]:
# Type Declaration
# 타입 선언
# :: "is an instance of"
In [1]:
# 변수, 함수인자는 물론,
# 표현식에도 타입선언을 할수있다.
# 타입이 안맞을경우 이런꼴을 보게된다.
(1+2)::AbstractFloat
In [2]:
# 타입이 맞을 경우
(1+2)::Int
Out[2]:
In [4]:
#변수에 타입선언.
function foo()
x::Int8 = 100
x
end
typeof( foo())
Out[4]:
In [6]:
let
x::Int8 = 0
local y::Int8
z::Int8 = 0
end
Out[6]:
In [9]:
# <: "is subtype of"
let
Integer <: Number
end
Out[9]:
In [10]:
let
Integer <: AbstractFloat
end
Out[10]:
In [13]:
# <: "is subtype of"
Int8 <: Signed
Out[13]:
In [ ]:
# Julia 에서 모든 값들은 객체(object)다.
# 객체의 멤버함수는 없다.
# object 에 속해있는 member function 은 없다.
# 멤버함수가 없는것이
# 이득을 가져온다.
# Julia 는 multiple dispatch 가 있으므로
# 객체에 한정된 멤버함수는 필요치 않다.
In [1]:
# composite type
# structure
# C++ 언어에 있는 구조체(struct) 를 만들어보자.
# type 키워드를 쓴다. struct 가 아니다.
type Foo
bar
baz::Int
qux::Float64
end
In [2]:
foo = Foo("Hello, world.", 23, 1.5)
Out[2]:
In [3]:
typeof( foo)
Out[3]:
In [4]:
fieldnames( foo)
Out[4]:
In [5]:
fieldnames( Foo)
Out[5]:
In [6]:
foo.bar
Out[6]:
In [7]:
foo.baz
Out[7]:
In [8]:
foo.qux
Out[8]:
In [9]:
foo.qux = 2
Out[9]:
In [10]:
foo.bar = 1//2
Out[10]:
In [11]:
# filed 가 없는 composite type 은 singletone 이다.
# 오직 하나의 인스턴스만 존재할 수 있다.
type NoFields
end
In [12]:
is( NoFields(), NoFields())
Out[12]:
In [13]:
# immutable composite type
# 변경불가 구조체
# type 이 아니라, immutable 을 쓴다.
immutable Complex
real::Float64
imag::Float64
end
In [14]:
typeof(Real)
Out[14]:
In [15]:
typeof(Int)
Out[15]:
In [18]:
# type union
IntOrString = Union{Int, AbstractString}
Out[18]:
In [19]:
1 :: IntOrString
Out[19]:
In [20]:
"Hello" :: IntOrString
Out[20]:
In [21]:
1.0 :: IntOrString
In [22]:
typeof(Union)
Out[22]:
In [23]:
fieldnames(Union)
Out[23]:
In [25]:
fieldnames(IntOrString)
Out[25]:
In [26]:
IntOrString.types
Out[26]:
In [27]:
# Parametric Types
# Parametric Composite Types
type Point{T}
x::T
y::T
end
In [28]:
typeof(Point)
Out[28]:
In [29]:
fieldnames(Point)
Out[29]:
In [30]:
t1 = Point{Float64}
Out[30]:
In [31]:
typeof( t1)
Out[31]:
In [32]:
fieldnames( t1)
Out[32]:
In [33]:
t2 = Point{AbstractString}
Out[33]:
In [34]:
typeof( t2)
Out[34]:
In [35]:
Point
Out[35]:
In [36]:
typeof( Point)
Out[36]:
In [37]:
Point{Float64} <: Point
Out[37]:
In [38]:
Point{AbstractString} <: Point
Out[38]:
In [39]:
IntOrString <: Point
Out[39]:
In [40]:
function norm(p::Point{Real})
sqrt( p.x^2 + p.y^2)
end
Out[40]:
In [41]:
function norm{ T <: Real }( p::Point{T} )
sqrt( p.x^2 + p.y^2)
end
Out[41]:
In [42]:
Point{Float64}(1.0, 2.0)
Out[42]:
In [43]:
typeof( ans)
Out[43]:
In [44]:
# 인자의 타입으로부터 유추할수 있으므로
# 이렇게 쓸수있다.
# 컴파일러는 안다.
# 이것이
# Point{Float64}(1.0, 2.0) 라는것을....
Point( 1.0, 2.0)
Out[44]:
In [45]:
typeof( ans)
Out[45]:
In [46]:
# 컴파일러는 안다.
# 이것이
# Point{Int64}(1,2) 라는것을....
Point(1, 2)
Out[46]:
In [47]:
typeof( ans)
Out[47]:
In [1]:
# Parametric Abstract Type
abstract Pointy{T}
In [49]:
Pointy{Int64} <: Pointy
Out[49]:
In [50]:
Pointy{1} <: Pointy
Out[50]:
In [51]:
Pointy{Float64} <: Pointy{Real}
Out[51]:
In [52]:
Pointy{Real} <: Pointy{Float64}
Out[52]:
In [2]:
type Point{T} <: Pointy{T}
x::T
y::T
end
In [3]:
Point{Float64} <: Pointy{Float64}
Out[3]:
In [4]:
Point{Real} <: Pointy{Real}
Out[4]:
In [5]:
Point{AbstractString} <: Pointy{AbstractString}
Out[5]:
In [6]:
Point{Float64} <: Pointy{Real}
Out[6]:
In [7]:
type DiagPoint{T} <: Pointy{T}
x::T
end
In [1]:
# parameter T 의 타입을 제한할수있다.
abstract Pointy{ T <: Real}
In [2]:
typeof((1, "foo", 2.5))
Out[2]:
In [3]:
typeof( Ptr)
Out[3]:
In [4]:
# Parametric Bits Types
bitstype 32 my_Ptr{T}
In [1]:
bitstype 64 my_Ptr{T}
In [2]:
Ptr{Float64} <: Ptr
Out[2]:
In [3]:
Ptr{Float64} <: Ptr
Out[3]:
In [4]:
UInt
Out[4]:
In [5]:
typeof( UInt)
Out[5]:
In [7]:
# type 은 object 이다.
In [8]:
# UInt 가 Integer 의 subtype 이냐
# Integer 가 UInt 의 supertype 이냐.
UInt <: Integer
Out[8]:
In [9]:
isa( 1, Int)
Out[9]:
In [10]:
isa( 1, AbstractFloat)
Out[10]:
In [11]:
# object 는 type 을 가진다.
# type 은 object 이다.
# 따라서, type 은 type 을 가진다.
typeof( Rational)
Out[11]:
In [13]:
typeof( Union{Real, Float64, Rational})
Out[13]:
In [14]:
typeof( Union{Real, ASCIIString})
Out[14]:
In [15]:
typeof(Union)
Out[15]:
In [16]:
typeof( DataType)
Out[16]:
In [17]:
super(UInt)
Out[17]:
In [18]:
super(Unsigned)
Out[18]:
In [20]:
super(Integer)
Out[20]:
In [21]:
super(Real)
Out[21]:
In [22]:
super(Number)
Out[22]:
In [24]:
super(Any)
Out[24]:
In [25]:
super(Any)
Out[25]:
In [26]:
super( Float64)
Out[26]:
In [27]:
super(AbstractFloat)
Out[27]:
In [28]:
super(Real)
Out[28]:
In [29]:
super(Real)
Out[29]:
In [30]:
super(Number)
Out[30]:
In [31]:
super(Any)
Out[31]:
In [32]:
1 != 1
Out[32]:
In [33]:
1 == 1
Out[33]:
In [9]:
# 특정타입의 상속 가계도를 알아보자.
# 어디까지 올라가는지 한번 보자.
let
sub_type = Float64
while true
println( sub_type)
super_type = super( sub_type)
if( super_type == sub_type)
break
end
sub_type = super_type
end
end
In [10]:
# Any 가 끝인가.
In [11]:
Any == Any
Out[11]:
In [ ]:
# Value types
In [12]:
# 이런 코드를 만들어 냈었지.
function firstlast(b::Bool)
return b ? "First" : "Last"
end
println(firstlast(true))
In [15]:
# 조건문 평가를 런타임이 아니라
# 컴파일타임에 수행하도록 할수가 있지.
firstlast(::Type{Val{true}}) = "First"
firstlast(::Type{Val{false}}) = "Last"
println(firstlast(Val{true}))
In [17]:
# 모든 파라메터는 Val 을 통해서 넘어간다.
function f1( a)
println( a)
end
Out[17]:
In [37]:
f1( Val{1})
In [20]:
typeof( Val{1})
Out[20]:
In [21]:
fieldnames( Val{1})
Out[21]:
In [22]:
Val{1}()
Out[22]:
In [23]:
typeof( Val{1}())
Out[23]:
In [24]:
println( Val{1}())
In [25]:
x1 = Nullable{Int64}()
Out[25]:
In [26]:
x2 = Nullable{Float64}
Out[26]:
In [27]:
x3 = Nullable{Vector{Int64}}()
Out[27]:
In [28]:
isnull(Nullable{Float64}())
Out[28]:
In [29]:
isnull(Nullable(0.0))
Out[29]:
In [30]:
get(Nullable{Float64}())
In [31]:
get(Nullable(1.0))
Out[31]:
In [32]:
get(Nullable{Float64}(), 0)
Out[32]:
In [33]:
get(Nullable(1.0), 0)
Out[33]: