13

I have been trying to use constants and variables in a class that refer by name to other constants and variables in the same class at the class level. AFAIK, as of Xcode 6 beta 4, Swift still doesn't have class variable support. What I'm wondering is whether the errors I see when trying to refer to other constants (let) or variables (var) are simply due to lack of class variable support?

You can refer to the constants and variables within a method or outside the class, you just don't seem to be able to reference by name at the class level. The following class shows several variations along with the errors you will see displayed in Xcode 6 beta 4.

This can be tested in a playground or regular .swift file.

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
    }
}

For reference, the original Objective-C code that led to this problem in Swift was from the CS193P SuperCard app where a C #define is used for a constant and then that constant is used to set a variable.

@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];
}
kasplat
  • 1,177
  • 3
  • 13
  • 16
  • I think it has more to do with self being unavailable at the class or struct level. There's no real guarantee that you aren't assigning garbage to some value (despite the lets) – CodaFi Jul 22 '14 at 00:51
  • None of the members you're declaring are class members. If you actually try "`class let value = 1`" you will see "Class variables not yet supported" but it seems this has nothing to do with your question. – jtbandes Jul 22 '14 at 01:19

1 Answers1

20

The two errors messages you're getting are actually a result of two different, but related, reasons.

error: Use of unresolved identifier 'self'

self refers to an instance of a type and does not exist until that type is considered fully initialized, and therefore cannot be used for default property values.

error: 'Simple.Type' does not have a member named 'someConstant'

Class variables and static variables are considered "type variables" of classes and structs, respectively. What this means is that they're defined as variables on the type itself, as opposed to an instance of that type. By this definition and the fact that you can't use self for default property values, it's clear that this error message is a result of Swift looking for a class variable named someConstant. Class variables are still not supported as of Beta 4.

The analogous code for structs, with type variables taken into account, compiles just fine:

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

    let referringConstant = someConstant
    var referringVar = someVariable

    let explicitTypeProperty = Simple.someConstant
}

Reference: my recollection of the "Properties" and "Initializers" chapters of The Swift Programming Language.

Andrew
  • 2,438
  • 1
  • 19
  • 19
  • Thanks Andrew. I made an addition to the original question showing the Objective-C that led me to the problem in Swift. I think you nailed the answer. – kasplat Jul 22 '14 at 05:53