Julia Language
튜플
수색…
통사론
- 에이,
- a, b
- a, b = xs
- ()
- (에이,)
- (a, b)
- (a, b ...)
- 튜플 {T, U, V}
- NTuple {N, T}
- 튜플 {T, U, Vararg {V}}
비고
튜플은 배열 보다 런타임 성능이 훨씬 뛰어납니다. 그 이유는 두 가지 유형이 더 정확하고 무변 성으로 인해 힙 대신 스택에 할당 될 수 있기 때문입니다. 그러나이 더 정밀한 타이핑은 컴파일 시간 오버 헤드와 타입 안정성을 얻기가 더 어려워집니다.
튜플 소개
Tuple
은 동일한 유형 또는 다른 유형 의 임의의 고유 한 객체로 이루어진 불변의 순서가 지정된 콜렉션입니다. 일반적으로 튜플은 (x, y)
구문을 사용하여 생성됩니다.
julia> tup = (1, 1.0, "Hello, World!")
(1,1.0,"Hello, World!")
터플의 개별 객체는 색인 구문을 사용하여 검색 할 수 있습니다.
julia> tup[1]
1
julia> tup[2]
1.0
julia> tup[3]
"Hello, World!"
그들은 iterable 인터페이스를 구현하므로 for
루프 를 사용하여 반복 할 수 있습니다.
julia> for item in tup
println(item)
end
1
1.0
Hello, World!
튜플은 또한 reverse
또는 length
와 같은 다양한 일반 콜렉션 함수를 지원합니다.
julia> reverse(tup)
("Hello, World!",1.0,1)
julia> length(tup)
3
또한 튜플은 any
, all
, map
또는 broadcast
포함한 다양한 상위 컬렉션 작업을 지원합니다.
julia> map(typeof, tup)
(Int64,Float64,String)
julia> all(x -> x < 2, (1, 2, 3))
false
julia> all(x -> x < 4, (1, 2, 3))
true
julia> any(x -> x < 2, (1, 2, 3))
true
빈 튜플은 ()
사용하여 만들 수 있습니다.
julia> ()
()
julia> isempty(ans)
true
그러나 한 요소의 튜플을 구성하려면 뒤에 오는 쉼표가 필요합니다. 이는 괄호 ( (
와 )
)가 튜플을 구성하는 대신 그룹화 연산으로 함께 처리되기 때문입니다.
julia> (1)
1
julia> (1,)
(1,)
일관성을 위해 둘 이상의 요소가있는 튜플에 대해서도 후행 쉼표를 사용할 수 있습니다.
julia> (1, 2, 3,)
(1,2,3)
튜플 유형
typeof
터플의 하위 유형입니다 Tuple
:
julia> typeof((1, 2, 3))
Tuple{Int64,Int64,Int64}
julia> typeof((1.0, :x, (1, 2)))
Tuple{Float64,Symbol,Tuple{Int64,Int64}}
다른 데이터 유형과 달리 Tuple
유형은 공변 입니다. 줄리아의 다른 데이터 유형은 일반적으로 불변합니다. 그러므로,
julia> Tuple{Int, Int} <: Tuple{Number, Number}
true
julia> Vector{Int} <: Vector{Number}
false
Tuple{Number, Number}
가 받아 들여지기 때문에 Tuple{Int, Int}
도 마찬가지입니다. 왜냐하면 두 요소가 모두 숫자이기 때문입니다. 즉위한 경우가 아니라 Vector{Int}
대 Vector{Number}
수용성 함수로서 Vector{Number}
부동 소수점 저장하고자 할 수있다 (예를 들면 1.0
) 또는 복소수 (예 1+3im
등의) 벡터.
튜플 유형의 공분산은 Tuple{Number}
(다시 Vector{Number}
와는 달리)이 실제로 추상 유형임을 의미합니다.
julia> isleaftype(Tuple{Number})
false
julia> isleaftype(Vector{Number})
true
Tuple{Number}
의 구체적인 아형은 Tuple{Int}
, Tuple{Float64}
, Tuple{Rational{BigInt}}
등을 포함합니다.
Tuple
유형은 무한 개수의 객체를 나타내는 마지막 매개 변수로 Vararg
를 포함 할 수 있습니다. 예를 들어, Tuple{Vararg{Int}}
는 임의의 수의 Int
포함하는 모든 튜플 유형이며, 가능하면 0입니다.
julia> isa((), Tuple{Vararg{Int}})
true
julia> isa((1,), Tuple{Vararg{Int}})
true
julia> isa((1,2,3,4,5), Tuple{Vararg{Int}})
true
julia> isa((1.0,), Tuple{Vararg{Int}})
false
Tuple{String, Vararg{Int}}
은 문자열 과 그 뒤에 임의의 수 (아마도 0)의 Int
로 구성된 튜플을 허용합니다.
julia> isa(("x", 1, 2), Tuple{String, Vararg{Int}})
true
julia> isa((1, 2), Tuple{String, Vararg{Int}})
false
공분산과 함께, 이것은 Tuple{Vararg{Any}}
모든 튜플을 설명한다는 것을 의미합니다. 사실, Tuple{Vararg{Any}}
은 Tuple
을 말하는 다른 방법 일뿐입니다.
julia> Tuple{Vararg{Any}} == Tuple
true
Vararg
는 정확히 첫 x 째 유형 매개 변수가 _ 생해야하는 = 수를 나타내는 두 Vararg
숫자 유형 매개 변수를 승인합니다. 기본적으로 지정되지 않은 경우이 두 번째 유형 매개 변수는 임의의 값을 취할 수있는 typevar입니다. 따라서 임의의 개수의 Int
가 위에있는 Vararg
에서 허용됩니다. 지정된 Vararg
끝나는 Tuple
유형은 자동으로 요청 된 요소 수 :
julia> Tuple{String,Vararg{Int, 3}}
Tuple{String,Int64,Int64,Int64}
지정된 Vararg
가진 균질 튜플에 대한 표기법이 존재합니다 : NTuple{N, T}
. 이 표기법에서 N
은 튜플의 요소 수를 나타내며 T
는 허용되는 유형을 나타냅니다. 예를 들어,
julia> NTuple{3, Int}
Tuple{Int64,Int64,Int64}
julia> NTuple{10, Int}
NTuple{10,Int64}
julia> ans.types
svec(Int64,Int64,Int64,Int64,Int64,Int64,Int64,Int64,Int64,Int64)
참고 NTuple
의 특정 크기 이상 단순히으로 표시됩니다 NTuple{N, T}
대신 확장의, Tuple
형태로, 그러나 그들은 여전히 같은 유형 :
julia> Tuple{Int,Int,Int,Int,Int,Int,Int,Int,Int,Int}
NTuple{10,Int64}
튜플 유형으로 디스패치
줄리아 함수 매개 변수 목록 자체 튜플, 때문에 발송 방법은 자신을 매개 변수를 통해 튜플의 다양한 종류에하는 것은 종종 "스플래"에 대한 자유로운 사용과, 다 자주 쉽게 ...
운영자입니다. 예를 들어, Base
에서 튜플에 대한 reverse
구현을 고려해보십시오.
revargs() = ()
revargs(x, r...) = (revargs(r...)..., x)
reverse(t::Tuple) = revargs(t...)
이 방법으로 튜플에 메소드를 구현하면 성능에 결정적인 유형 안정성 이 유지됩니다. @code_warntype
매크로를 사용하면이 방법에 오버 헤드가 없다는 것을 알 수 있습니다.
julia> @code_warntype reverse((1, 2, 3))
Variables:
#self#::Base.#reverse
t::Tuple{Int64,Int64,Int64}
Body:
begin
SSAValue(1) = (Core.getfield)(t::Tuple{Int64,Int64,Int64},2)::Int64
SSAValue(2) = (Core.getfield)(t::Tuple{Int64,Int64,Int64},3)::Int64
return (Core.tuple)(SSAValue(2),SSAValue(1),(Core.getfield)(t::Tuple{Int64,Int64,Int64},1)::Int64)::Tuple{Int64,Int64,Int64}
end::Tuple{Int64,Int64,Int64}
약간 읽기는 어렵지만 여기 코드는 원래 튜플의 3 번째, 2 번째 및 1 번째 값을 가진 새로운 튜플을 생성하는 것입니다. 많은 컴퓨터에서로드 및 저장으로 구성된 매우 효율적인 LLVM 코드로 컴파일됩니다.
julia> @code_llvm reverse((1, 2, 3))
define void @julia_reverse_71456([3 x i64]* noalias sret, [3 x i64]*) #0 {
top:
%2 = getelementptr inbounds [3 x i64], [3 x i64]* %1, i64 0, i64 1
%3 = getelementptr inbounds [3 x i64], [3 x i64]* %1, i64 0, i64 2
%4 = load i64, i64* %3, align 1
%5 = load i64, i64* %2, align 1
%6 = getelementptr inbounds [3 x i64], [3 x i64]* %1, i64 0, i64 0
%7 = load i64, i64* %6, align 1
%.sroa.0.0..sroa_idx = getelementptr inbounds [3 x i64], [3 x i64]* %0, i64 0, i64 0
store i64 %4, i64* %.sroa.0.0..sroa_idx, align 8
%.sroa.2.0..sroa_idx1 = getelementptr inbounds [3 x i64], [3 x i64]* %0, i64 0, i64 1
store i64 %5, i64* %.sroa.2.0..sroa_idx1, align 8
%.sroa.3.0..sroa_idx2 = getelementptr inbounds [3 x i64], [3 x i64]* %0, i64 0, i64 2
store i64 %7, i64* %.sroa.3.0..sroa_idx2, align 8
ret void
}
다중 반환 값
튜플은 여러 반환 값에 자주 사용됩니다. 반복 가능한 인터페이스 의 두 가지 함수 ( next
와 done
)를 포함한 많은 표준 라이브러리는 두 개의 관련 있지만 구별되는 값을 포함하는 튜플을 반환합니다.
튜플 주위의 괄호는 특정 상황에서 생략 될 수 있으므로 여러 반환 값을 더 쉽게 구현할 수 있습니다. 예를 들어 실수의 양과 음의 제곱근을 반환하는 함수를 만들 수 있습니다.
julia> pmsqrt(x::Real) = sqrt(x), -sqrt(x)
pmsqrt (generic function with 1 method)
julia> pmsqrt(4)
(2.0,-2.0)
Destructuring 할당은 여러 개의 반환 값을 언팩하는 데 사용될 수 있습니다. 변수 a
와 b
에 제곱근을 저장하려면 a
과 같이 작성하면됩니다.
julia> a, b = pmsqrt(9.0)
(3.0,-3.0)
julia> a
3.0
julia> b
-3.0
또 다른 예로 divrem
과 fldmod
함수가 있습니다.이 함수는 정수 (truncating 또는 floored) 와 나누기 및 나머지 연산을 동시에 수행합니다.
julia> q, r = divrem(10, 3)
(3,1)
julia> q
3
julia> r
1