Ответ
Для классов:
В extension класса можно добавлять только convenience-инициализаторы:
class Person {
let name: String
let age: Int
// Designated инициализатор - только в основном объявлении
init(name: String, age: Int) {
self.name = name
self.age = age
}
}
extension Person {
// Convenience инициализатор - можно в extension
convenience init(name: String) {
self.init(name: name, age: 0)
}
// Еще один convenience инициализатор
convenience init() {
self.init(name: "Unknown", age: 0)
}
}
Для структур и перечислений:
Можно добавлять любые инициализаторы, так как у них нет наследования:
struct Point {
var x: Double
var y: Double
}
extension Point {
// Можно добавить designated инициализатор для структуры
init(value: Double) {
self.x = value
self.y = value
}
}
enum CompassDirection {
case north, south, east, west
}
extension CompassDirection {
// Инициализатор для enum
init(from string: String) {
switch string.lowercased() {
case "n": self = .north
case "s": self = .south
// ...
default: self = .north
}
}
}
Ограничения для extension классов:
- Нельзя добавлять designated инициализаторы
- Нельзя добавлять required инициализаторы
- Нельзя добавлять deinitializer
- Нельзя добавлять инициализаторы, если класс помечен как
@frozen
Практический пример с UIKit:
extension UIViewController {
// Convenience инициализатор для UIViewController
convenience init(nibName: String? = nil) {
self.init(nibName: nibName, bundle: nil)
}
}
Рекомендации:
- Используйте extension для добавления convenience инициализаторов, которые предоставляют значения по умолчанию
- Добавляйте инициализаторы в extension для лучшей организации кода
- Помните, что required инициализаторы должны быть в основном объявлении класса
Ответ 18+ 🔞
А, ну это про инициализаторы в экстеншенах! Ёпта, тема-то какая хитрая, как жопа с замочной скважиной. Слушай, сейчас разжую, как мартышке банан.
Вот смотри, с классами тут отдельная песня, пиздец. В экстеншен к классу ты можешь пихать только convenience-инициализаторы. Designated — нихуя, только в основном теле класса. Это как закон: основную дверь (designated) ставишь при стройке дома, а дополнительные калиточки (convenience) уже можешь приделать потом, на участке (в extension).
class Person {
let name: String
let age: Int
// Вот это твой главный, designated инициализатор. Его место тут, в святая святых.
init(name: String, age: Int) {
self.name = name
self.age = age
}
}
extension Person {
// А это уже convenience — пожалуйста, хуячь в extension, никто не запретит.
convenience init(name: String) {
self.init(name: name, age: 0) // Обязательно зовёт designated
}
// И вот этот тоже можно, ебать его в сраку.
convenience init() {
self.init(name: "Unknown", age: 0)
}
}
А вот для структур и энамов — полная свобода, волнение ебать! У них наследования нет, поэтому им похуй. Хочешь — designated инициализатор в экстеншен? Да хуярь!
struct Point {
var x: Double
var y: Double
}
extension Point {
// Для структуры — да хоть designated, да хоть на ушах стой. Можно.
init(value: Double) {
self.x = value
self.y = value
}
}
Главные запреты для классов, блядь:
- Designated инициализаторы — нихуя. Только в основном теле.
- Required инициализаторы — тоже нихуя. Тоже только в основном теле.
- Деинициализатор (
deinit) — забудь, как страшный сон. Его место только в классе. - Если класс
@frozen— тогда ваще нихуя нельзя, сиди и не рыпайся.
Практический пример, чтобы не быть мудаком:
extension UIViewController {
// Convenience — значит, можно. Удобная калиточка.
convenience init(nibName: String? = nil) {
self.init(nibName: nibName, bundle: nil)
}
}
Итог, чувак:
Хочешь добавить инициализатор с дефолтными значениями, чтобы не писать одно и то же сто раз? Засовывай convenience init в extension — это канон. Организация кода будет огонь, а не пиздец. Но про required и designated — даже не думай, там тебе сразу компилятор впендюрит ошибку. Всё, рот меня чих-пых, вопрос закрыт.