2014-12-02 1 views
4

Вопрос: Имеет ли у Юлии строгий подтип оператора?У Джулии есть строгий оператор подтипа?

Примечание: Оператор <: является не строгий оператор подтипа, так как Number <: Number вычисляет true. Меня интересует оператор, который будет оценивать до false для Number <: Number, но true за Int <: Number.

Возможное использование случай: Рассмотрим функцию, определенную:

MyFunc{T<:Union(Int, String)}(x::Array{T, 1}, y::Array{T, 1)}) 

В настоящее время функция ограничивает x и y быть массивами одного и того же типа, где этот тип является Int, String или Union(Int, String). Но со строгим оператором подтипа я мог заставить входные массивы иметь тип Int или String и устранить (довольно нечетный) сценарий Union(Int, String).

ответ

4

Я не думаю, что есть такой оператор в Джулию, но это, вероятно, будет довольно легко написать функцию, которая делает то же проверку:

strictSubType{T,U}(::Type{T}, ::Type{U}) = T <: U && T != U # note: untested! 

Однако, у меня есть сомнение вашего случая использования , Если то, что вы действительно хотите, это что-то вроде

function my_func{T<:String}(x::Vector{T}, y::Vector{T}) 
    # handle strings 
    # note that String is an abstract type, inherited by e.g. ASCIIString and UTF8String 
end 

function my_func(x::Vector{Int}, y::Vector{Int}) 
    # handle ints 
    # note that Int is a concrete type (actually an alias for either Int32 or Int64, 
    # depending on your platform) so no generic type parameter is necessary 
end 

тогда напишите, что вместо этого. Если у вас есть части логики, которые могут быть разделены, реорганизуйте ее в отдельные методы, где вы можете, возможно, расслабить параметры типа (или полностью опустить их).

Update, в ответ на ваш комментарий:

Если оба метода должны сделать точно то же самое, то вы, вероятно, лучше использовать duck typing, и просто не уточняя типы функции аргументы у всех:

funciton my_func(x, y) 
    # handle ints, strings and anything else that supports things you need (e.g. > and <) 
end 

Юлия компилирует конкретные методы для каждой комбинации типа вы называете вещи, так что вы все равно получите как быстрый код; если функция устойчива по типу, то она будет быстрой для любой комбинации (см. документы Julia для более подробного объяснения того, как это работает). Если вы хотите, чтобы убедиться, что два аргумента векторы, и что они того же типа, я бы рекомендовал делать диагональную отправку (также более подробно описано в документации):

function my_func{T}(x::AbstractVector{T}, y::AbstractVector{T}) 
    # handle stuff 
end 

Обратите внимание, что я использую AbstractVector, а не Vector - это позволяет использовать какой-либо другой тип контейнера, который также ведет себя как вектор с элементами типа T, максимизируя удобство использования вашей функции для других кодеров.

+1

Интересно, спасибо, что ответили. Я думаю, что буду следовать твоему предложению и использовать свою функцию для проверки. Что касается прецедента, функция, которую я имел в виду, была бы одинаковой для входов «String» или «Int» - это может произойти, если, например, функция выполняет только больше или меньше, чем сравнение типов, которые действительны для как строки, так и числа.Поэтому представляется бесполезным выписывать два идентичных метода (которые различаются только по типу ввода). Но было бы неплохо устранить случай «Союза», поскольку массивы типа «Союз» могут пострадать от проблем с производительностью ... –

+1

@ColinTBowers: В этом случае более «юлианский» способ сделать это - указать тип типа на всех - тогда я могу использовать вашу функцию с любым типом, который я указываю (который вы даже не знаете, существует), и единственное, что требуется от меня, это реализовать любые операции, которые вам нужны, в этом случае больше/меньше сравнений. Эта концепция обычно упоминается как [duck typing] (http://en.wikipedia.org/wiki/Duck_typing) и считается идиоматичной в Юлии. –

+0

@ColinTBowers Я написал сообщение для публикации, чтобы уточнить, что я имею в виду. Я надеюсь, что это полезно =) –