首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Julialang:在抽象类型上强制接口

Julialang:在抽象类型上强制接口
EN

Stack Overflow用户
提问于 2019-06-11 09:54:42
回答 2查看 561关注 0票数 4

我一直在尝试理解Julialang的类型系统,但一些设计方面仍然让我感到困惑。我希望有人能澄清一下。

所以这里的问题是关于抽象类型及其具体实现。从I understand Julia抽象类型的内容来看,抽象类型不会对它们的具体实现施加任何约束。因此,不能保证在抽象类型上工作的方法也会在该类型的具体实现上工作。

我知道Julia不使用类也不遵循继承。但是我只想避免在我的代码中产生各种各样的bug。如果有不同的设计范例,那么请有人回答下面的问题2。

所以我有两个问题。

  1. ,这仍然是语言的工作方式吗?我只想确认一下,自从这篇博文发布以来,一切都没有改变。用户如何围绕这个看似vulnerability?

的东西设计他们的软件?

链接帖子中的问题示例:

代码语言:javascript
复制
abstract type AbstractPerson end
abstract type AbstractStudent <: AbstractPerson end
abstract type AbstractTeacher <: AbstractPerson end

struct Person <: AbstractPerson
  name::String    
end

struct Student <: AbstractStudent
  name::String  
  grade::Int
  hobby::String
end

struct MusicStudent <: AbstractStudent
  grade::Int
end

现在,如果我在抽象类型上创建一些方法。

代码语言:javascript
复制
get_name(x::AbstractPerson) = x.name
p1 = Person("elroy")
get_name(p1)

>"elroy"

因此,即使MusicStudentAbstractPerson的子类型,MusicStudent也没有name属性。这意味着可以观察到以下行为。

代码语言:javascript
复制
m1 = MusicStudent(10)
get_name(m1)


ERROR: type MusicStudent has no field name

Stacktrace:
 [1] getproperty(::Any, ::Symbol) at ./sysimg.jl:18
 [2] get_name(::MusicStudent) at ./In[2]:1
 [3] top-level scope at In[13]:2

所以这里的问题是,Julia允许我使用基本上不完整的构造函数来实例化类型变量m1。当我尝试运行该函数时,它只会给我一个错误。

这意味着如果我为抽象类型编写一个函数,我不能保证该类型的每个具体实现都有相同的接口。这似乎会使代码变得非常脆弱,因为开发人员不知道哪些类型实现了哪些属性和方法。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-06-11 10:24:46

这种行为不就是Person实现中的一个bug吗?如果你真的希望行为没有异常,你可以定义一个默认的方法:

代码语言:javascript
复制
julia> get_name(p::AbstractPerson) = try return p.name catch y return "" end
get_name (generic function with 1 method)

julia> m1 = MusicStudent(10)
MusicStudent(10)

julia> get_name(m1)
""

我认为潜在的困难可能是在Julia中你不能继承名为"name“的数据字段作为对象层次结构的一部分。这里有一个关于真正问题的很好的讨论(请参阅@forward宏的提及):

https://discourse.julialang.org/t/composition-and-inheritance-the-julian-way/11231

票数 2
EN

Stack Overflow用户

发布于 2019-06-12 03:39:54

基本的答案是,在julia中,方法的接口被认为是定义为接受该类型的元素的方法。例如,AbstractArray指定实现应该实现getIndexsize。之所以不将字段作为接口的一部分,是因为这样做不会考虑到内存效率高的代码,因为每种类型都可以以最合理的方式定义方法。例如,如果我想创建一个名为Bob的类型,它是所有名为bob的人的子类型,我不想每次都存储他的名字。通过使用方法,Julia允许以意想不到的方式进行更多的未来扩展。

从技术上讲,这种方法失去了“安全性”,但唯一的方法是如果您使用可能不存在的字段编写代码,在这种情况下,您将得到一个错误。这种类型的安全性没有多大用处,因为它只会给您带来一个会减慢开发速度的编译错误。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56535455

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档