- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
protocol Multi {
associatedtype T
associatedtype U
func printSelf()
}
extension Multi where T == Int, U == Float {
func printSelf() {
print("Int & Float!")
}
}
extension Multi where T == String, U == Int {
func printSelf() {
print("String & Int!")
}
}
extension Multi {
func printSelf() {
print("Unknown")
}
}
class MultiImplementationIntFloat: Multi {
typealias T = Int
typealias U = Float
}
class MultiImplementationStringInt: Multi {
typealias T = String
typealias U = Int
}
class MultiImplementationInvalid: Multi {
typealias T = Float
typealias U = String
}
let m1 = MultiImplementationIntFloat()
m1.printSelf()
let m2 = MultiImplementationStringInt()
m2.printSelf()
let m3 = MultiImplementationInvalid()
m3.printSelf()
SemaReal 10.03.2018 16:04 # +1
Это не совсем честно, потому что завист от типа m, а не от переданных в printSelf аргументов, с таким же успехом ты мог printSelf в каждом классе переопределить:)
Desktop 10.03.2018 17:49 # −1
class blahblah { }
и где-то в недрах клиентского кода
extension blahblah: Multi {...}
И получаешь миксин
SemaReal 10.03.2018 17:59 # +2
Я имел ввиду разницу в точки зрения диспатча: всё таки тип m2 известен в момент компеляции, и потому свифт может подобрать нужный метод статически. Котлин тоже так может, например:)
Полезность extensionов я под сомнение не ставлю, это супер-крутая фича для method discovery (которая, кстати, была в ObjC [категории называлась вродеъ задолго до Kotlin, и наверное до C#)
Desktop 10.03.2018 21:55 # 0
Категории ОбжСи сосут у Свифта в данном случае: там нет default implementation
SemaReal 10.03.2018 22:04 # +1
Представь себе такой псевдокод
В твоем случае это не так, потому что тип data известен в момент компеляции.
А вот с перегрузкой методов или с visitor это бы сработало.
>>Категории ОбжСи сосут у Свифта в данном случае: там нет default implementation
Ты про print("Unknown")?
Удобно, да. Я почти ничего не знаю про Swift:( Во время моего близкого знакомства с Apple везде был Objc, кажется только ARC завезли.
Desktop 11.03.2018 11:13 # 0
"Сами generic functions тоже не похожи. В CL они не привязываются к одному конкретному типу. Например, можно определить функцию (defgeneric intersects (a b)) и написать методы для случаев (defmethod intersects ((a rectangle) (b circle))), (defmethod intersects ((a circle) (b circle))), (defmethod intersects ((a interval) (b point)))…
В рантайме будет выбран наиболее подходящий эффективный метод. Т.е. это настоящие мультиметоды." (c) roman с той разницей, что выбор будет в компайлтайме.
> В твоем случае это не так, потому что тип data известен в момент компеляции.
У тебя он тоже известен, это ж Mammal.
> А вот с перегрузкой методов или с visitor это бы сработало.
- превед ООПед
> Ты про print("Unknown")?
- не. Я про то, что можно:
1) определить протокол
2) заэкстендить его, дав некоторым методам default implementation
3) потом заэкстендить какой-то класс этим протоколом, voila!, класс умеет в default implementation методов протокола
В ObjC так нельзя (ну или я чего-то не знаю).
Ещё таким образом можно сэмулировать @optional из обж сей. Экстендим метод пустым телом, кому реально надо, реализует сам.
SemaReal 11.03.2018 15:11 # 0
И что? Этой информации не достаточно чтобы выбрать метод в комплайт тайме.
А в твоем случае достаточно. Смотри:
Компилятор в твоем примере на строке 42 (m1.printSelf()) думает: "а что за метод такой -- printSelf? Ах, у нас же тип m1 это MultiImplementationIntFloat, значит и метод понятно какой". Экстеншены в котлине резолвятся статически, в момент компиляции, думаю что и в Свифте -- тоже.
А в моем примере он НЕ знает типа data и вынужден отложить решение о выборе метода до рантайма, как если бы это был виртуальный метод.
В том-то и разница.
>>- превед ООПед
Ну в мейнстрим ЯПах с ООП обычно только так и бывает)
>> класс умеет в default implementation методов протокола
Но весь код, юзающий класс, придется перекомпилировать, да?
>> сэмулировать @optional из обж сей.
А у вас нету optinal? А спросить respondsToSelector можно?
Desktop 12.03.2018 00:58 # 0
- да.
> А у вас нету optinal? А спросить respondsToSelector можно?
- у нас это в свифте? Только в @objc протоколах. В обычных свифтовых нету. Спросить respondsToSelector можно у классов, которые известны рантайму ObjC (т.е. потомки NSObject)
Desktop 10.03.2018 22:02 # 0
SemaReal 10.03.2018 22:20 # +1
Допустим, у меня есть user. Я хочу его удалить. Интуитивно я ищу метод delete(), но конечо его нет в классе User (потому что он ничего про удаление себя не знает).
Тогда я говорю user.[cntrl space] и IDE находит мне все его extension методы (по сути те, где он является первым аргументом). Так я нахожу свой метод. Но так делает Intellij для Kotlin, и кажется R# для C#. Делает-ли так XCode для Swift я не знаю (думаю что может быть и нет), но может AppCode делает.
Вот куда его класть -- вопрос. Это вообще часто большая проблема. Люди любят насоздавать всяких UserUtils где хрен чего найдешь.
Проблему можно решить документированием API, но где (кроме публичных проектов) такое бывает? В проприетарном коде, которым пользуются 20 человек в одной конторе, почти никого такого нет:(((
Вот если бы IDE умели "найти все публичные методы, доступные в этом модуле/пакете, где определённого класса инстанс является одним из параметров" то может быть было бы не плохо и без exntesions, но всё равно явный вызов метода выглядит приятнее.
bormand 11.03.2018 02:48 # 0
Емнип, в squeack (одна из реализаций smalltalk) была такая фишка.
Desktop 11.03.2018 11:25 # 0
- проверил, для классов умеет, для протоколов нет. XCode это блокнот, они рефакторинг для свифта только к 4 версии языка смогил добавить.
> Вот куда его класть -- вопрос.
- ну на крайняк в TypeNameExtensions.swift.
> Интуитивно я ищу метод delete(), но конечо его нет в классе User (потому что он ничего про удаление себя не знает).
Тогда я говорю user.[cntrl space] и IDE находит мне все его extension методы
> Проблему можно решить документированием API
- когда что-то ищется интуитивно и не находится, то kill hire repeat
SemaReal 11.03.2018 15:15 # 0
У меня тоже было такое ощущение, например его парсер не умеет восстанавливаться: забыл ] в одном месте и всё дерево пошло по песде. Я помню что думал пересесть на AppCode, но побоялся что сториборды не будут там работать:)
>>- ну на крайняк в TypeNameExtensions.swift.
Немножечко "god objfile"
>>то kill hire repeat
У нас в большинстве проектов оче хуёво с API:((
chtulhu 11.03.2018 18:38 # +1
они уже пару лет точно забили на UI, потому что яббл в каждом релизе что-нибудь меняет. Я пишу код в appcode, ui - в xcode. Коллеги жалюутся на то, что в xcode постоянно падает парсер и он превращается в блокнот. Appcode как-то стабильнее, но тоже может не увидеть либу или какой-нибудь экстеншн
И да, сториборды - говно. Лучше делать отдельные xib
SemaReal 11.03.2018 22:15 # 0
почему? Мне нравилось визуально наблюдать перемещение экранов, и сигвеи тоже нравились
Desktop 11.03.2018 23:21 # +1
SemaReal 11.03.2018 23:34 # +1
Нужна пессимистичная блокировка, как была в source safe:)
Desktop 12.03.2018 00:55 # +1
Но вообще да, много маленьких сторибордов вместо одной большой + lock, если возможно
Desktop 12.03.2018 01:01 # 0
SemaReal 12.03.2018 01:30 # 0
roman-kashitsyn 11.03.2018 13:36 # 0
Desktop 11.03.2018 14:19 # 0
> Вся суть настоящих мультиметодов в том, что можно сложить объекты разных типов в гетерогенный контейнер и работать с ними универсальным образом.
- зачем нужна гетерогенная динамическая метушня, если в общем случае проблем с ней больше? Вон Пи сокрушался по поводу того, что эксепшон вылетит в C#, если нет нужной перегрузки. Кстати, как CL будет вести себя в таком случае?
roman-kashitsyn 11.03.2018 14:33 # 0
>> let m1 = MultiImplementationIntFloat()
> зачем нужна гетерогенная динамическая метушня
Ну вот есть у тебя все объекты какой-нибудь игры, ты хочешь положить их в дерево, чтобы быстро считать столкновения.
> Кстати, как CL будет вести себя в таком случае?
Если совсем нет реализации, кинет исключение "кондишен". Тех конфликтов, которые пи нашёл в c#, там не будет, там по-другому "перегрузки" разрешаются. http://govnokod.ru/23894#comment407460
Desktop 11.03.2018 14:59 # 0
и поехали
> Ну вот есть у тебя все объекты какой-нибудь игры, ты хочешь положить их в дерево, чтобы быстро считать столкновения.
- composition же. У объектов должны быть geometric bodies, по ним и считать. Geometric bodies по идее должны обладать одинаковыми геометрическими свойствами, так что гетерогенность вроде и ни к чему здесь. А, если хочется динамики, не взять ли duck typing с чем-то типа forwardInvocation (это из смолтолка пришло вроде)?
roman-kashitsyn 11.03.2018 15:25 # 0
Это что-то меняет? Ну хранишь ты геометрию вместо реальных объектов. Всё равно потом надо найти, каким объектам эта геометрия принадлежит, и вызвать соответствующую типам функцию.
Desktop 11.03.2018 17:13 # 0
Но в ObjC даже проще сделать то, о чем ты говоришь
roman-kashitsyn 11.03.2018 20:42 # 0
Ну так можно утверждать, что Tree<GameObject> никакой не гетерогенный контейнер. В нём же только GameObject-ы лежать могут.
Допустим, у тебя какой-нибудь "однородный" SpaceTree<Polygon>. Дерево помогло тебе быстро посчитать, что полигон p1 теперь пересекается с полигоном p2. Что дальше-то будем делать? Теперь надо понять, чем именно являются полигоны p1 и p2 и вызвать соответствующую функцию, ибо корабли, к примеру, взрываются и аннигилируют, а астероиды распадаются на несколько мелких астероидов. Вот тут ты и будешь пилить наколенный аналог мультиметодов.
CHayT 11.03.2018 21:27 # +4
Внутри него есть некий отдалённый аналог "мультиметодов", т.к. нужно обрабатывать столкновения soft и rigid bodies, например, но количество типов сущностей известно и невелико, а требования к перфомансу существенны, так что CLOS и там нафиг не впёрся.
doctor_stertor 11.03.2018 21:45 # 0
1024-- 11.03.2018 21:51 # 0
http://i5.otzovik.com/2017/03/03/4590066/img/6653156.jpeg
roman-kashitsyn 11.03.2018 22:14 # 0
> CLOS и там нафиг не впёрся
Это всё и так понятно, можно десятилетиями песать опупенные сайты игоры без всякого там «CLOS».
Я просто поясняю, почему (в теории) в компайл-тайме не всегда перегрузку выбрать можно.
guest8 19.02.2019 02:28 # −999
6E3yMHblu_nemyx 19.02.2019 03:57 # 0
guest8 18.04.2019 03:17 # −999
guest8 28.04.2019 05:15 # −999
PACTPOBblu_nemyx 28.04.2019 14:58 # 0
guest8 31.07.2019 03:38 # −999
bormand 31.07.2019 04:06 # 0
Пиарить свои девайсы в письмах покупателей - это уже норма? Мир ебанулся... Как вообще эппл до такого скатился?
guest8 10.08.2019 10:34 # −999
HEMECTHblu_nemyx 12.08.2019 00:49 # 0
petux 12.08.2019 00:51 # 0
HEMECTHblu_nemyx 12.08.2019 00:54 # 0
petux 12.08.2019 00:55 # 0
HEMECTHblu_nemyx 12.08.2019 00:56 # 0
petux 12.08.2019 00:59 # 0
HEMECTHblu_nemyx 12.08.2019 01:02 # 0
guest8 10.08.2019 08:09 # −999