"Class.Type" не имеет члена с именем "переменная", просто отсутствие поддержки переменных класса?

Я пытаюсь использовать константы и переменные в классе, который ссылается по имени на другие константы и переменные в том же классе на уровне класса. AFAIK, с Xcode 6 beta 4, Swift по-прежнему не поддерживает поддержку переменных класса. Мне интересно, возникают ли ошибки, возникающие при попытке ссылаться на другие константы (let) или переменные (var), из-за отсутствия поддержки переменных класса?

Вы можете ссылаться на константы и переменные внутри метода или вне класса, вы просто не можете ссылаться по имени на уровне класса. Следующий класс показывает несколько вариантов, а также ошибки, которые вы увидите в Xcode 6 beta 4.

Это можно протестировать на игровой площадке или в обычном файле.swift.

class Simple {

    let someConstant = 0.50

    var someVariable = 1

    // uncomment let and var lines to see the errors

    // error: 'Simple.Type' does not have a member named 'someConstant'
    // let referringConstant = someConstant
    // error: Use of unresolved identifier 'self'
    // let referringConstant = self.someConstant

    // error: 'Simple.Type' does not have a member named 'someVariable'
    // var referringVar = someVariable
    // error: Use of unresolved identifier 'self'
    // var referringVar = self.someVariable

    // can't do class constants or variables yet either
    // let referringConstant = Simple.someConstant
    // var referringVar = Simple.someVariable

    func simpleMethod() {
        // both of these forms are valid as long as it is unambiguous
        let referToConstant = someConstant
        let referToVariable = someVariable

        var anotherConstant = self.someConstant
        var anotherVariable = self.someVariable
    }
}

Для справки исходный код Objective-C, который привел к этой проблеме в Swift, был из приложения SuperCard CS193P, где для константы используется константа С#define, а затем эта константа используется для установки переменной.

@interface PlayingCardView()
@property (nonatomic) CGFloat faceCardScaleFactor;
@end

@implementation PlayingCardView

#pragma mark - Properties

@synthesize faceCardScaleFactor = _faceCardScaleFactor;

#define DEFAULT_FACE_CARD_SCALE_FACTOR 0.90

- (CGFloat)faceCardScaleFactor
{
    if (!_faceCardScaleFactor) _faceCardScaleFactor = DEFAULT_FACE_CARD_SCALE_FACTOR;
        return _faceCardScaleFactor;
}

- (void)setFaceCardScaleFactor:(CGFloat)faceCardScaleFactor
{
    _faceCardScaleFactor = faceCardScaleFactor;
    [self setNeedsDisplay];
}

Ответ 1

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

Ошибка: использование неразрешенного идентификатора 'self'

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

error: "Simple.Type" не имеет члена с именем "someConstant",

Переменные класса и статические переменные считаются "переменными типа" классов и структур соответственно. Это означает, что они определены как переменные для самого типа, а не для экземпляра этого типа. По этому определению и тому факту, что вы не можете использовать self для значений свойств по умолчанию, ясно, что это сообщение об ошибке является результатом Swift, ищущего переменную класса с именем someConstant. Переменные класса по-прежнему не поддерживаются с Beta 4.

Аналогичный код для структур с учетом переменных типа компилируется просто отлично:

struct Simple {
    static let someConstant = 0.50
    static var someVariable = 1

    let referringConstant = someConstant
    var referringVar = someVariable

    let explicitTypeProperty = Simple.someConstant
}

Ссылка: мое воспоминание о главах "Свойства" и "Инициализаторы" языка Swift Programming.