Как мы проводим занятия в Юлии?

У меня проблема с написанием уроков в Джулии. Я просмотрел документацию и не видел никаких документов по классам.

В Python классы, например,

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

Как это возможно в Джулии?

Краткий ответ: мы не делаем.

carstenbauer 22.05.2019 15:21

Класс похож на struct + методы. В Джулии они (намеренно) не объединены вместе. Так что просто создайте struct и добавьте методы. docs.julialang.org/en/latest/manual/types

tholy 22.05.2019 15:27

Так что это структуры + методы вместо классов в Джулии. Вау спасибо.

kkirui 22.05.2019 17:51

@tholy, пожалуйста, дайте мне простой пример, чтобы продемонстрировать это хотя бы для лучшего понимания.

kkirui 22.05.2019 17:52
3 метода стилизации элементов HTML
3 метода стилизации элементов HTML
Когда дело доходит до применения какого-либо стиля к нашему HTML, существует три подхода: встроенный, внутренний и внешний. Предпочтительным обычно...
Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Будучи разработчиком веб-приложений, легко впасть в заблуждение, считая, что приложение без JavaScript не имеет права на жизнь. Нам становится удобно...
Flatpickr: простой модуль календаря для вашего приложения на React
Flatpickr: простой модуль календаря для вашего приложения на React
Если вы ищете пакет для быстрой интеграции календаря с выбором даты в ваше приложения, то библиотека Flatpickr отлично справится с этой задачей....
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Клиент для URL-адресов, cURL, позволяет взаимодействовать с множеством различных серверов по множеству различных протоколов с синтаксисом URL.
11
4
7 632
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ближе всего к классам с методами в 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)

Модуль кажется излишним - действительно, это похоже на неуместное использование модулей. Но ваша структура Dog и функция bark — отличные примеры того, как получить эту функциональность.

Michael K. Borregaard 22.05.2019 21:24

Это игрушечный пример. При переносе существенного класса из чего-то вроде C++ пользователь может захотеть эмулировать закрытые методы, что позволяет использовать вид модуля (хотя и не полностью), поскольку будут экспортированы только общедоступные методы.

Bill 22.05.2019 22:39

Большое спасибо. Теперь я понимаю больше об использовании модулей

kkirui 23.05.2019 12:12
Ответ принят как подходящий

У Юли нет занятий. Вместо этого мы определяем новые типы, а затем определяем методы для этих типов. Методы не "принадлежат" типам, с которыми они работают. Вместо этого можно сказать, что метод принадлежит общая функция с тем же именем, что и метод. Например, существует множество версий («методов») функции length; вместе они образуют общую функцию length.

Вот расширенный пример юлианского подхода к программированию с типами и методами. Новые типы объявляются с помощью ключевого слова struct:

struct Person
    name::String
    age::Int64
end

Теперь мы можем определить методы для типа 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.")

Методы могут быть определены для различных комбинаций типов аргументов. Чтобы проиллюстрировать это, давайте сначала определим несколько новых типов:

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.")

На данный момент мы видим, что мы определили три разных метода с одним аргументом для 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

Обратите внимание на комментарий в выводе methods(bio): «3 метода для универсальной функции 'bio'». Мы видим, что bio — это общая функция, в котором в настоящее время определены 3 метода для разных функций подписи. Теперь давайте добавим метод с двумя аргументами для bio:

function bio(person::Person, possession)
    bio(person)
    bio(possession)
end

Обратите внимание, что эта функция является общей в аргументе 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

Теперь давайте создадим несколько экземпляров наших типов:

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

Итак, наконец, мы можем протестировать наши 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.

Примечание: модули используются в основном для управления пространство имен. Один модуль может содержать определения для нескольких типов и нескольких методов.

Я считаю, что это более подробно описывает мой вопрос.

kkirui 29.05.2019 12:50

Другое дело, что я думаю, что было бы лучше использовать «тип растения» вместо «типа» при определении структуры для растения. Это имеет смысл, потому что «тип» зарезервирован, хотя он и устарел, но когда вы пишете код с «типом», Джулия думает, что вы хотите создать «тип». И, наконец, насколько важны следующие строки кода? имя(d::Собака) = d.name цвет(d::Собака) = d.color видов(::Собака) = "собака"

kkirui 29.05.2019 17:39

@kkirui Хорошее замечание о «типе». Хотя я использую Julia v1.1 и не вижу никаких предупреждений об использовании «типа». Я думаю, что это должно быть нормально в Джулии v1.0 или выше.

Cameron Bieganek 29.05.2019 18:18

В этом примере методы name, color и species кажутся немного лишними. Однако они помогают определить «интерфейс» для абстрактного типа Pet. Обратите внимание, что метод bio(p::Pet) работает с любым подтипом Pet, потому что методы name, color и species реализованы для каждого подтипа. Это позволяет изменить внутреннее представление Cats и Dogs в любой момент в будущем, если это необходимо, пока методы name, color и species все еще реализованы и по-прежнему возвращают тот же тип вывода.

Cameron Bieganek 29.05.2019 18:23

Внутри класса в Python есть эта функция ``` python def __init__(): blah end ``` Можно ли добавить в приведенный выше ответ? @Кэмерон Бейганек

kkirui 16.06.2019 22:04

Я не совсем понимаю, почему все методы (name, color, species и т. д.) объявлены вне структуры. Я думал, что целью класса было хранить набор атрибутов и методов, принадлежащих ему, а не глобальному пространству имен. (Например, чтобы я мог вызывать их с помощью точечной записи: alice.bio()). Могу ли я сделать это в Джулии?

Bill 26.06.2020 06:31

У @Bill Julia нет занятий. Функции в Julia используют множественную отправку, что означает, что правильный метод для отправки выбирается путем просмотра типов всех позиционных аргументов, а не только первого аргумента. Тип объекта, предоставленного в качестве первого аргумента функции, не «владеет» методом больше, чем типы других аргументов, поэтому не имеет смысла связывать методы со структурами. На самом деле происходит обратное — все различные методы для foo можно рассматривать как члены функции общийfoo.

Cameron Bieganek 26.06.2020 20:49

@Bill Такой подход к разделению типов данных и функций/методов распространен в функциональных языках, включая R.

Cameron Bieganek 26.06.2020 20:53

Спасибо @Cameron Beiganek. Я читаю о множественной отправке. Думаю, я понял, но как мне избежать практической проблемы конфликтов имен? Например, я создал метод для своего объекта: step(gym::CartPole, u) и поместил их оба в модуль, и теперь я получаю WARNING: both CartPoleBTEnv and Base export "step"; uses of it in module Main must be qualified. Есть ли какие-нибудь простые примеры или учебные пособия о том, как это сделать?

Bill 26.06.2020 22:25

Для начинающих, таких как я, я нашел небольшое введение в функции и методы в Джулии здесь: Думай, Джулия.

Bill 26.06.2020 23:07

@Bill Ваш вопрос о конфликтах имен достоин отдельного вопроса о переполнении стека. Но вкратце, вы можете либо переименовать свою функцию, вызвать ее через CartPoleBTEnv.step(), либо сделать ее расширением функции Base.step. Последний вариант удобен, но не идеален, так как функция Base step имеет значение «получить размер шага объекта AbstractRange», что совершенно отличается от смысла вашей step функции. Мне жаль, что они выбрали имя step для этой функции в Base. На мой взгляд, stepsize было бы лучше.

Cameron Bieganek 28.06.2020 04:43

Это не просто step. Имена функций, такие как begin, end, break, catch, show, export, будут создавать похожие конфликты. В конце концов, я расширил Base.step, но тогда вы живете в страхе, что какой-то другой процесс может однажды вызвать ваш метод!

Bill 28.06.2020 22:19

Другие вопросы по теме