#swift3 #fluent #api-design
#swift3 #свободно #api-дизайн
Вопрос:
В Swift 3 многие методы были переименованы. Согласно одной из сессий на WWDC, предлоги в именах методов перемещаются в имя параметра:
UIView.animateWithDuration(1)
-> UIView.animate(withDuration: 1)
UIStoryboard.instantiateViewControllerWithIdentifier("some stuff")
-> UIStoryboard.instantiateViewController(withIdentifier: "some stuff")
Я думал, что viewWithTag(1)
они будут переименованы в view(withTag: 1)
, но это не так!
Это даже упоминается в руководстве API:
Особенно когда тип параметра — NSObject, Any, AnyObject или фундаментальный тип, такой как Int или String, информация о типе и контекст в точке использования могут не полностью передавать намерение. В этом примере объявление может быть ясным, но сайт использования расплывчатый.
func add(_ observer: NSObject, for keyPath: String) grid.add(self, for: graphics) // vague
Чтобы восстановить ясность, перед каждым слабо типизированным параметром следует указать существительное, описывающее его роль:
func addObserver(_ observer: NSObject, forKeyPath path: String) grid.addObserver(self, forKeyPath: graphics) // clear
Я также обнаружил, что SKNode.addChild
это тоже не переименовано!
Вопрос:
Почему эти методы не переименованы? Они забыли о них? Или есть исключения из правил API? Если да, то что это такое?
Ответ №1:
Я изучаю алгоритм, описанный в Swift Evolution 0005.
- viewWithTag
Первый шаг сокращения имени — это:
Удалите тип результата из заголовка преобразований, сохраняющих тип. В частности, когда
- тип получателя совпадает с типом результата
- и имя типа сопоставляется в начале первой части селектора
- и за совпадением следует предлог
view
часть на самом деле удаляется первой.
forTag
Также удаляется на шаге 3, поэтому результатом является пустой селектор.
Это сталкивается с
Ограничения на сокращение…
- Никогда не делайте часть селектора полностью пустой.
Поэтому обрезка не выполняется.
- addChild
addChild
, addSubview
, addGestureRecognizer
следуйте все тому же шаблону, на самом деле в спецификации есть пример:
- Никогда не удаляйте суффикс из базового имени метода, который соответствует свойству заключающего класса:
Эта эвристика не позволяет нам создавать слишком общие имена для методов, которые концептуально изменяют свойство класса.
… Если бы мы отбросили
GestureRecognizer
, оставив толькоadd
, мы получили бы метод, который концептуально изменяетgestureRecognizers
свойство, но использует для этого слишком общее имя:
В общем, они не могут забыть о некоторых методах, потому что переименование (импорт) происходит автоматически.
Комментарии:
1. Что насчет
addChild
метода? Разве это не должно бытьadd
? Это по другой причине?2. @Sweeper расширил ответ. Не заметил, что вы просили два разных метода. Алгоритм довольно сложный, но он имеет большой смысл.