Julia中有一个概念,比如C ++的typedef

问题描述 投票:3回答:2

我正在尝试学习julia,并开始重写我的一个C ++程序。

我在找到一个在Julia中表示以下概念的好方法时遇到了问题。

我有一些结构,所有这些都是某种集合。假设我有一个AddressBook和一个PhotoAlbum。每个系列都有不同的元素。现在,在C ++中,如果我知道将PhotoAlbum传递给函数,则很容易创建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
}
julia typedef equivalent
2个回答
2
投票

如果我正确理解你的问题,我会说你不必考虑它,因为编译器会知道所需的类型。例如,在上面的代码中,当你调用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)


-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
© www.soinside.com 2019 - 2024. All rights reserved.