簡體   English   中英

制作無參數類型具有“默認值”

[英]Making a no parameter type have “defaults”

我基本上想要做以下事情:

typealias CVODE_BDF CVODE_BDF{:Newton,:Dense}

也就是說,允許用戶傳遞給我的函數CVODE_BDF ,如果他們沒有設置任何類型參數,則將其解釋為CVODE_BDF{:Newton,:Dense} 我知道typealias實際上不起作用,但有沒有辦法模擬這個? 就像在函數中一樣,讀取T.parameters[1]並以某種方式看到它是空的?

如果函數接受該類型的對象而不是類型本身,則可以執行此操作。 例如

type MyObject{T}
end


const DefaultMyObject = MyObject{Int64}()

f{T}(x::MyObject{T}=DefaultMyObject) = T

f(), f(MyObj{Float64}())

(Int64,Float64)

一種可能性是通過構造函數設置類型參數( {:Newton,:Dense} )。

以下是Julia(rational.jl)中定義的有理數字類型的示例:

immutable Rational{T<:Integer} <: Real
    num::T
    den::T

    function Rational(num::T, den::T)
        if num == 0 && den == 0
            error("invalid rational: 0//0")
        end
        g = gcd(den, num)
        num = div(num, g)
        den = div(den, g)
        new(num, den)
    end
end

在您的示例中,您可以在CVODE_BDF類型定義中定義構造函數並檢查類型,如果未設置則返回{:Newton,:Dense}

這樣的事情對你有用嗎?

type A{T, S} end

功能實現:

f{T, S}(::Type{A{T,S}}) = T, S  

設置默認值的包裝器:

f(::Type{A}) = f(A{1, 1})
f{T}(::Type{A{T}}) = f(A{T, 1})
f{S}(::Type{A{:default, S}}) = f(A{1, S})

結果:

f(A)                 # (1,1)
f(A{3,4})            # (3,4)
f(A{0})              # (0,1)
f(A{:default, 2})    # (1,2)

因為最后一次調用有點難看,如果需要最大的靈活性,對象可能是更好的選擇。 此外,構造函數可以對參數強制執行約束,因此不需要在函數中檢查它們。

編輯:

如果你的函數有多個參數,那么為每個參數組合添加方法就太多了。 相反,可以為每種類型定義一個默認方法(為簡潔起見,只需一個參數):

type A{T} end
type B{T} end

default{T}(::Type{A{T}}) = A{T}
default(::Type{A}) = A{1}
default{T}(::Type{B{T}}) = B{T}
default(::Type{B}) = B{1}

f{T,S}(::Type{A{T}}, ::Type{B{S}}) = T*S
f{T<:A, S<:B}(a::Type{T}, b::Type{S}) = f(default(a), default(b))

在當前的夜晚,這沒有運行時開銷:

julia> @code_llvm f(A,B)

define i64 @julia_f_62099(%jl_value_t*, %jl_value_t*) #0 {
top:
  ret i64 1
}

就在這里。 如果您Type{CVODE_BDF} ,則可以檢查生成的對象的參數。 如果CVODE_BDF為“空”,則返回帶有通用參數的CVODE_BDF類型,否則它們將是使用的特定參數。

示例(使用Array因為我沒有方便的CVODE_BDF ):

julia> Type{Array}.parameters
svec(Array{T,N})

julia> Type{Array{Float64, Int64}}.parameters
svec(Array{Float64,Int64})

功能示例:

function f{T}(t::T)
  if Type(t).parameters == Type(Array).parameters
    t = Array{Int64, 1};
  end
  return t;
end

julia> f(Array{Int64, 1})
Array{Int64,1}

julia> f(Array{Float64, 1})
Array{Float64,1}

julia> f(Array)
Array{Int64,1}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM