Каким образом `size` инициализируется и принимается в качестве параметра, если он не находится ни в каком подклассе, ни в свойстве суперкласса, ни '_' используется перед ним? - PullRequest
3 голосов
/ 11 апреля 2019

В функции init() (строка 68) внутри class TriangleAndSquare, почему возникает необходимость инициализации метки параметра size и как она принимается в качестве параметра, даже если это не свойствов любом подклассе (включая сам этот класс) или суперклассе?

Кроме того, как size принимается в качестве аргумента (строки 69 и 70), кажется, для типа Square: NameShape (строка 14) в его *Функция 1008 * (строка 17), когда class Square: NameShape даже не имеет size в качестве одного из своих свойств [как и size в суперклассе: NameShape (строка 1)], и при этом оно не инициализируетсяв 'class Square: NameShape`?

Разве не должно быть подчеркивания _ перед size в class TriangleAndSquare init() функциональном параметре (строка 68), возможно, как init(_ size: Double, name: String), такчто любая метка аргумента при создании объекта может быть принята в качестве его параметра?

Этот код взят из файла GuidedTour.playground из их языка программирования Swift 4.2 (он находится в Swift 5версия той же книги).Код находится в разделе «Классы и объекты».

Я уже переварил документы Apple и несколько хороших видеоуроков о цели и природе: инициализации, аргументов, меток аргументов, параметров и меток параметровно я думаю, мне нужно другое представление / объяснение по ним.

1    class NamedShape {
2        var numberOfSides: Int = 0
3        var name: String
4    
5        init(name: String) {
6            self.name = name
7        }
8    
9        func simpleDescription() -> String {
10          return "A shape with \(numberOfSides) sides."
11       } 
12    }
13
14    class Square: NamedShape {
15        var sideLength: Double
16    
17        init(sideLength: Double, name: String) {
18            self.sideLength = sideLength
19            super.init(name: name)
20            numberOfSides = 4
21        }
22    
23        func area() -> Double {
24            return sideLength * sideLength
25        }
26    
27        override func simpleDescription() -> String {
28            return "A square with sides of length \(sideLength)."
29        } 
30    }
31
32    class EquilateralTriangle: NamedShape {
33        var sideLength: Double = 0.0
34    
35        init(sideLength: Double, name: String) {
36            self.sideLength = sideLength
37            super.init(name: name)
38            numberOfSides = 3
39        }
40    
41        var perimeter: Double {
42            get {
43                return 3.0 * sideLength
44            }
45            set {
46                sideLength = newValue / 3.0
47            }
48        }
49    
50        override func simpleDescription() -> String {
51            return "An equilateral triangle with sides of length \ (sideLength)."
52        } 
53    }
54
55    class TriangleAndSquare {
56        var triangle: EquilateralTriangle {
57            willSet {
58                square.sideLength = newValue.sideLength
59            }
60        }
61
62        var square: Square {
63            willSet {
64                triangle.sideLength = newValue.sideLength
65            }
66        }
67
68        init(size: Double, name: String) {
69            square = Square(sideLength: size, name: name)
70            triangle = EquilateralTriangle(sideLength: size, name: name)
71        } 
72    }

Я ожидал, что в нем будет ошибка, но это не очень распространенная инициализация, принятие меток параметров и аргументов не вызвало никаких ошибок в AppleБыстрая книга.

1 Ответ

0 голосов
/ 11 апреля 2019

Наличие аргумента, помеченного size в дозе инициализатора, не обязательно означает, что существует свойство с именем size.Это просто ввод значений для класса, чтобы инициализировать любое из его свойств.В этом случае size передается, чтобы стать sideLength нижележащего квадрата и Equностороннего треугольника.

Вам не нужно передавать переменную с тем же именем, что и метка аргумента, важен только тип.sideLength это просто метка, она принимает тип Double.size - это переменная с типом Double.Следовательно, square = Square(sideLength: size, name: name) имеет смысл.

Если вы укажете в функции метку аргумента и имя переменной, это будет выглядеть примерно так: func foo(n x : Int){print(x)}, где n - метка аргумента, x - этоимя переменной при обращении к ней внутри функции, Int является типом этого аргумента.Эта функция будет вызываться с foo(n:1)

Подчеркивание используется, если вы хотите, чтобы у аргумента не было метки.

Например, func foo(_ x : Int){print(x)} можно вызвать с помощью foo(1).Вы можете спросить, когда это будет полезно?Именно тогда аргументы вашей функции настолько очевидны, что добавление метки не обеспечивает большей читабельности.

например, func sum(_ a : Int, _ b: Int){return a + b} очевидно, что добавление метки к любому из входных данных вообще не улучшает читаемость, так как они не имеют смысла.sum(a:1,b:2) НЕ является улучшением читабельности по сравнению с sum(1,2).

Если вы не предоставите отдельную метку аргумента и имя переменной, одно и то же имя будет использоваться и как метка аргумента, и как имя переменной.

например func foo(x : Int){print(x)} должен вызываться с foo(x : 1)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...