我一直在试图了解类型系统,Julialang
但是某些设计方面仍然使我感到困惑。我希望有人能澄清一下。
所以这里的问题是关于抽象类型及其具体实现。据我了解, Julia
抽象类型对其具体实现没有任何约束。因此,不能保证适用于Abstract类型的方法将适用于该类型的具体实现。
我知道Julia不使用类或遵循继承。但是我只想避免在我的代码中生成各种错误。如果有不同的设计范例,那么有人可以回答下面的问题2。
所以我有两个问题。
这仍然是语言工作的方式吗?只是为了确认自博客发布以来没有任何变化。
用户如何围绕这个看似漏洞设计软件?
链接帖子中的问题示例:
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
现在,如果我在抽象类型上创建一些方法。
get_name(x::AbstractPerson) = x.name
p1 = Person("elroy")
get_name(p1)
>"elroy"
因此,即使MusicStudent
是的子类型AbstractPerson
,MusicStudent
也没有name
属性。这意味着观察到了以下行为。
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
使用实质上不完整的构造函数实例化类型变量。当我尝试运行该功能时,它只会给我一个错误。
因此,这意味着如果我为Abstract Type编写函数,则不能保证该Type的每个具体实现都具有相同的接口。这似乎将使代码变得非常脆弱,因为开发人员将不知道哪种类型实现哪些属性和方法。
这种行为不只是在实施人员中的错误吗?如果您确实希望行为无一例外地发生,则可以定义一个默认方法:
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中,您不能继承称为“名称”的数据字段作为对象层次结构的一部分。这里对这个真正的问题进行了很好的讨论(请参阅@forward宏的提及):
https://discourse.julialang.org/t/composition-and-inheritance-the-julian-way/11231
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句