Julia 中有没有像 C++ 的 typedef 这样的概念
Is there a concept in Julia like C++'s typedef
我正在尝试学习 julia,并从重写我的一个 C++ 程序开始。
我在寻找一种在 Julia 中表示以下概念的好方法时遇到问题。
我有一些结构,它们都是某种集合。假设我有一个 AddressBook 和一个 PhotoAlbum。每个系列都有非常不同的元素。现在,在 C++ 中,如果我知道 PhotoAlbum 已传递给函数,则创建 Photo 类型的变量非常容易。
我想不出 julia 中的等效方法。理想情况下,编译器应该确切地知道集合由哪种类型组成,以便它可以尽可能地优化。
这就是我在 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
}
如果我正确理解你的问题,我会说你不必考虑它,因为编译器会知道所需的类型。例如,在上面的代码中,当您调用 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
,它预期 return 集合中的一种元素。对于此功能,您可以为特定类型添加方法以获取有关它们所持有的元素类型的信息。然后你可以在你的代码中简单地 运行 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)
.
由于 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
我正在尝试学习 julia,并从重写我的一个 C++ 程序开始。
我在寻找一种在 Julia 中表示以下概念的好方法时遇到问题。
我有一些结构,它们都是某种集合。假设我有一个 AddressBook 和一个 PhotoAlbum。每个系列都有非常不同的元素。现在,在 C++ 中,如果我知道 PhotoAlbum 已传递给函数,则创建 Photo 类型的变量非常容易。
我想不出 julia 中的等效方法。理想情况下,编译器应该确切地知道集合由哪种类型组成,以便它可以尽可能地优化。
这就是我在 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
}
如果我正确理解你的问题,我会说你不必考虑它,因为编译器会知道所需的类型。例如,在上面的代码中,当您调用 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
,它预期 return 集合中的一种元素。对于此功能,您可以为特定类型添加方法以获取有关它们所持有的元素类型的信息。然后你可以在你的代码中简单地 运行 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)
.
由于 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