我正在尝试学习朱莉娅,并且首先重写了我的C ++程序之一。
我在寻找一种很好的方法来表达朱莉娅以下概念时遇到问题。
我有一些结构体,它们都是某种集合。假设我有一个地址簿和一个相册。每个集合都有非常不同的元素。现在,如果我知道将PhotoAlbum传递给函数,则在C ++中创建Photo类型的变量非常容易。
我想不起来朱莉娅的另一种方式。理想情况下,编译器应该确切知道集合包含哪种类型,以便它可以尽可能地进行优化。
这就是我在C ++中的做法
class AddressBook
{
public:
typedef PersonalDetail Element;
}
class PhotoAlbum
{
public:
typedef Photo Element;
}
template<typename Collection>
void printFirstElement<Collection>(const Collection& c)
{
const typename Collection::Element firstElement = //c.first();...
// do something with firstElement
}
答案 0 :(得分:2)
如果我正确理解了您的问题,我会说您不必考虑这个问题,因为编译器会知道所需的类型。例如,在上面的代码中,当您调用first(c)
(相当于c.first()
时),此变量的类型将在编译时知道(您可以通过运行{{1}来确认) })。
如果您要提供一个完整的小型工作示例,我可以为此提供一个工作代码。
一个更高级的主题是将一些元数据附加到您的类型。有几种方法可以做到。让我向您展示其中一个-通过参数化抽象类型。
@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
当然这是MWE,而且我不确定代码中是否需要它(如果显示少量完整的工作代码,我们可以讨论最佳实施策略)。
也许根本不需要这样的东西。例如,您有一个标准函数julia> ab = AddressBook()
AddressBook()
julia> pa = PhotoAlbum()
PhotoAlbum()
julia> getcollectiontype(ab)
PersonalDetail
julia> getcollectiontype(pa)
Photo
,该函数应返回集合中的元素类型。对于此功能,您可以为特定类型添加方法,以获取有关它们所持有的元素类型的信息。然后,您可以简单地在代码中运行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)
。
答案 1 :(得分:-1)
由于Julia中的变量可以容纳类型,因此您可以这样做
struct PersonalDetail
end
struct Photo
end
struct AddressBook
Element
AddressBook(Element=PersonalDetail) = new(Element)
end
struct PhotoAlbum
Element
PhotoAlbum(Element=Photo) = new(Element)
end
PhotoAlbum()
话虽如此,您无需指定函数类型就可以编写函数
function printFirstElement(c)
@show c[1]
end
printFirstElement([AddressBook()])
printFirstElement([PhotoAlbum()])
printFirstElement([rand([AddressBook() PhotoAlbum()])])
printFirstElement(1:5) # doesn't specify element type with `Element`, but we can still access its first element