"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.