我们如何在 Julia 上课?

kki*_*rui 10 julia

我在 Julia 中编写类时遇到问题。我看过文档,但没有看到任何关于课程的文档。

在 Python 中,类是,例如,

class Dog:
   # ----blah blah---

Run Code Online (Sandbox Code Playgroud)

这在 Julia 中怎么可能?

Cam*_*nek 21

朱莉娅没有课。相反,我们定义新类型,然后在这些类型上定义方法。方法不由它们操作的类型“拥有”。相反,可以说一个方法属于与该方法同名的通用函数。例如,该length函数有很多版本(“方法”);它们一起构成了泛型函数length

这是使用类型和方法进行编程的“Julian”方法的扩展示例。使用struct关键字声明新类型:

struct Person
    name::String
    age::Int64
end
Run Code Online (Sandbox Code Playgroud)

现在我们可以在Person类型上定义方法:

name(p::Person) = p.name
age(p::Person) = p.age

bio(p::Person) = println("My name is ", name(p)," and I am ", age(p), " years old.")
Run Code Online (Sandbox Code Playgroud)

可以为参数类型的不同组合定义方法。为了说明这一点,让我们首先定义一些新类型:

abstract type Pet end

struct Cat <: Pet
    name::String
    color::String
end

name(c::Cat) = c.name
color(c::Cat) = c.color
species(::Cat) = "cat"

struct Dog <: Pet
    name::String
    color::String
end

name(d::Dog) = d.name
color(d::Dog) = d.color
species(::Dog) = "dog"

bio(p::Pet) = println("I have a ", color(p), " ", species(p), " named ", name(p), ".")

struct Plant
    type::String
end

type(p::Plant) = p.type
bio(p::Plant) = println("I have a ", type(p), " house plant.")
Run Code Online (Sandbox Code Playgroud)

此时我们可以看到,我们已经为 定义了三种不同的单参数方法bio

julia> methods(bio)
  3 methods for generic function "bio":
[1] bio(p::Plant) in Main at REPL[17]:1
[2] bio(p::Person) in Main at REPL[4]:1
[3] bio(p::Pet) in Main at REPL[14]:1
Run Code Online (Sandbox Code Playgroud)

注意输出中的注释methods(bio):“通用函数'bio'的3种方法”。我们看到这bio是一个通用函数,目前为不同的函数签名定义了 3 个方法。现在让我们为 增加一个两个参数的方法bio

function bio(person::Person, possession)
    bio(person)
    bio(possession)
end
Run Code Online (Sandbox Code Playgroud)

请注意,此函数在possession参数中是通用的,因为bio(possession)无论possession是植物、猫还是狗,对 的内部调用都将起作用!所以我们现在总共有四种方法bio

julia> methods(bio)
  4 methods for generic function "bio":
[1] bio(p::Plant) in Main at REPL[17]:1
[2] bio(p::Person) in Main at REPL[4]:1
[3] bio(p::Pet) in Main at REPL[14]:1
[4] bio(person::Person, possession) in Main at REPL[18]:1
Run Code Online (Sandbox Code Playgroud)

现在让我们创建一些我们类型的实例:

alice = Person("Alice", 37)
cat = Cat("Socks", "black")
dog = Dog("Roger", "brown")
plant = Plant("Boston Fern")
Run Code Online (Sandbox Code Playgroud)

所以最后我们可以测试我们的bio方法:

julia> bio(alice, cat)
My name is Alice and I am 37 years old.
I have a black cat named Socks.

julia> bio(alice, dog)
My name is Alice and I am 37 years old.
I have a brown dog named Roger.

julia> bio(alice, plant)
My name is Alice and I am 37 years old.
I have a Boston Fern house plant.
Run Code Online (Sandbox Code Playgroud)

旁注:模块主要用于命名空间管理。单个模块可以包含多种类型和多种方法的定义。

  • @Bill Julia 没有课程。Julia 中的函数使用多重分派,这意味着通过查看所有位置参数的类型(而不仅仅是第一个参数)来选择正确的分派方法。作为函数第一个参数提供的对象的类型并不比其他参数的类型更“拥有”该方法,因此将方法与结构捆绑在一起是没有意义的。事实上,情况正好相反——“foo”的所有不同方法都可以被视为通用函数“foo”的成员。 (2认同)

Bil*_*ill 10

在 Julia 中,最接近使用方法的类是模块:

module DogClass

export Dog, bark

struct Dog
    name::String
end

function bark(d::Dog)
    println(d.name, " says woof!")
end

end #MODULE

using .DogClass  # note the . here, means look locally for module, not library

mydog = Dog("Fido")

bark(mydog)
Run Code Online (Sandbox Code Playgroud)

  • 这是一个玩具示例。当从 C++ 之类的东西移植一个实质性的类时,用户可能想要模拟私有方法,使用模块排序允许(尽管不完全),因为只有公共方法会被导出。 (4认同)
  • 该模块似乎是多余的 - 事实上,这似乎是对模块的不当使用。但是您的 Dog 结构和 bark 函数是如何获得此功能的很好的例子。 (2认同)