Julia 类型系统和行为

apo*_*sis 3 interface class typing julia

我仍在努力理解朱莉娅的类型。例如,假设我想定义一个Animal对象的结构。以打字稿为例,我会这样做:

interface Animal {
    sound: string;
}

function sing(animal: Animal) {
    console.log(animal.sound);
}

const dog: Animal = {
    sound: 'woof',
};

// OR
class Dog implements Animal {
    sound = 'woof';
    // other Dog methods here
    run() {}
}

// Wrong implementations are caught immediately
const cow: Animal = {
    noise: 'moo'
}

// Error: Type '{ noise: string; }' is not assignable to type 'Animal'.
// Object literal may only specify known properties, and 'noise' does not exist in type 'Animal'.
Run Code Online (Sandbox Code Playgroud)

我怎样才能在朱莉娅中做到这一点?换句话说,Animal需要有一个.sound. 这是我尝试过的:

abstract type Animal end

function sing(animal::Animal) 
    println(animal.sound)
end

struct Dog <: Animal
    sound::AbstractString
end

function run(dog::Dog) end

struct Cow <: Animal
    noise::AbstractString
end
Run Code Online (Sandbox Code Playgroud)

但:

  • 我没有从 IDE 收到任何关于 sing 不适用于所有Animal实现的警告
  • 当我尝试运行时,sing(Cow("moo"))我确实收到错误,但在函数中sing!: ERROR: type Cow has no field sound

我缺少什么?如果我在运行前没有收到警告,如何维护大型代码库?由于我无法对具体类进行子类型化,因此如何定义行为?

Prz*_*fel 5

Julia 不是面向对象的,因此采用 OO 通常不太舒服。

\n

大多数情况下,您会希望使用多重分派来定义不同对象类型的行为,例如:

\n
abstract type Animal end\n\ngetsound(::T) where T <: Animal = throw(ErrorException("not implemented for $T"))\nstruct Dog <: Animal end\nstruct Cow <: Animal end\nstruct Cat <: Animal\n   specialsound::String\nend\ngetsound(::Dog) = "hau"\ngetsound(cat::Cat) = cat.specialsound\nsing(animal::Animal) = println(getsound(animal))\n
Run Code Online (Sandbox Code Playgroud)\n

这是用法:

\n
julia> sing(Dog())\nhau\n\njulia> sing(Cat("mew"))\nmew\n\njulia> sing(Cow())\nERROR: not implemented for Cow\n
Run Code Online (Sandbox Code Playgroud)\n

现在关于 IDE - 在 VS Codium 中注释掉getsound(::T)并不会强调牛。然而,这确实看起来像是可以添加的东西,因为编译器将其检测为错误(假设getsound(::T) where T <: Animal未定义):

\n
julia> @code_typed sing(Cow())\nCodeInfo(\n1 \xe2\x94\x80     Main.getsound(animal)::Union{}\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80     unreachable\n) => Union{}\n
Run Code Online (Sandbox Code Playgroud)\n