Если я правильно понимаю вашу проблему, я бы сказал, что вам не нужно об этом думать, потому что компилятор будет знать требуемые типы.Например, в приведенном выше коде, когда вы вызываете first(c)
(это будет эквивалент c.first()
), тип этой переменной будет известен во время компиляции (вы можете подтвердить это, запустив @code_warntype
в вашей функции).
Если бы вы предоставили полный небольшой рабочий пример, я мог бы дать вам рабочий код для этого.
Более сложная тема - присоединение метаданных к вашим типам.Есть несколько способов сделать это.Позвольте мне показать вам один из них - через параметрический абстрактный тип.
abstract type AbstractCollection{T} end
struct PersonalDetail end
struct AddressBook <: AbstractCollection{PersonalDetail} end
struct Photo end
struct PhotoAlbum <: AbstractCollection{Photo} end
getcollectiontype(::AbstractCollection{T}) where T = T
и теперь вы можете написать что-то вроде этого, чтобы извлечь метаданные
julia> ab = AddressBook()
AddressBook()
julia> pa = PhotoAlbum()
PhotoAlbum()
julia> getcollectiontype(ab)
PersonalDetail
julia> getcollectiontype(pa)
Photo
Конечно, это MWE, и я не уверен, нужно ли вам это в вашем коде (если вы показываете небольшой полный рабочий код, мы можем обсудить лучшую стратегию реализации).
Также что-то подобное может вообще не понадобиться.Например, у вас есть стандартная функция eltype
, которая должна возвращать тип элемента в коллекции.Для этой функции вы можете добавить методы для ваших конкретных типов, чтобы получить информацию о типе элемента, который они содержат.Затем вы можете просто запустить eltype(collection)
в своем коде и снова - во время компиляции - у вас будет информация о типе элемента коллекции.
Также обратите внимание, что типы в Julia также являются значениями, например, следующимкод просто работает, и компилятор знает все типы по мере необходимости (функция f
пытается преобразовать свой второй аргумент y
в тип своего первого аргумента x
, используя конструктор типов):
julia> f(x,y) = typeof(x)(y)
f (generic function with 1 method)
julia> f(10, 2.0)
2
julia> f(10.0, 2)
2.0
julia> @code_warntype f(10.0, 2)
Body::Float64
1 ─ %1 = (Base.sitofp)(Float64, y)::Float64
└── return %1
Вышеприведенное определение эквивалентно следующему f(x::T,y) = T(y)
.