Declaring a constant in swift - ios

As I read the swift guide it says: The value of a constant doesn’t need to be known at compile time, but you must assign it a value exactly once.
I tried in REPL but without any luck:
let aConst;
aConst=23;
So how to declare a constant without setting initial value?

Example
let myConstant = getSomeValueFromMethod()
This is what it means that the value doesn't have to be known at compile time...

You can't declare a constant, then assign it at the global scope. If you have to do something like this, use a variable instead. When a constant is declared at global scope, it must be initialized with a value.
Docs

You can't just declare a constant without assigning it some sort of value. The compiler needs to know that the constant will have some sort of value. Consider the following example where a constant "isTablet" is computed based on variables that aren't known until runtime.
let isTablet = {
if (UIDevice.currentDevice().userInterfaceIdiom == .Pad) {
return true
} else {
return false
}
}()

Another example beside Suthan's:
var someVar: NSString
...
someVar = "Some String"
let someUnknownConstant = someVar

Related

how is it more efficient to use final/const instead of var?

final/const are nice to keep a variable's value from changing, but is it more efficient to use than using var to declare the variable? I wasn't able to find if i gain any efficiency by using final/const over using var.
Ok, let me try to explain.
class Foo {
var bar = 4;
function doSomething() {
return 3 + bar;
}
}
Must compute an addition everytime doSomething is called at runtime, because "bar" might change. If bar is final, the compiler can compute at compiletime. After all the remaining is something like:
class Foo {
// compiler erased "bar" and substituted any occurence by the value
function doSomething() {
return 7; // nothing to be computed at runtime
}
}
Note: most compilers detect a privat var as const, if it is never changed within its scope. But if the field is public, the compiler still won't know.

Variable name conflicts with function name leads to "Variable used within its own initial value"

Having this function
private func date(from string: String) {
// Do thing with string
}
when calling it with
let date = date(from: "11:30")
it produces the following error
Variable used within its own initial value
obviously changing the code to
let anythingButDate = date(from: "11:30")
will make the error go away but I am trying to understand why there is a conflict between variable name and method name in the first place.
UPDATE:
To be more precise - I understand that the compiler is having issues with giving the variable and the function the same name but I am curious why can't it distinguish that one is a variable name and the other is a function name.
There is no big distinction between functions and variables because even a variable can hold a function or closure. What you have is a conflict of identifiers.
You can use
date = self.date(...)
to make the intent clear.
Your function is called date, even though it has a parameter it will conflict if you´re trying to call a variable the same name in this case date. What happens is that the compiler tries to use the declared constant date to assign its own initial value.
When you use anythingButDate then it´s fine because your function is not called that and you don´t have any other function called anythingButDate.
let date = date(from: "11:30") // will not work
let datex = date(from: "11:30") // will work
let anythingButDate = date(from: "11:30") // will work

How is 'let' implemented?

I pulled this example straight from this Apple page
struct FixedLengthRange {
var firstValue: Int
let length: Int
}
and if you assign an instance of this structure to a constant,
let rangeOfFourItems = FixedLengthRange(firstValue: 0, length: 4)
it says we can't change its property values even if it is declared as 'var'
This makes me wonder how let is implemented? I hope any assignments to it can be detected at compile time and show compile error. But in the above case, why does it apply to every property of the structure, regardless of how it is defined?
I tried to search for this, finding it very difficult to search with keyword 'let' as it is quite common term.
Can anyone help me to understand this?
It's because a struct is a value type. This means it cannot be mutated in place.
Thus, if we have a variable rangeOfFourItems that is a FixedLengthRange struct instance, and we want to set rangeOfFourItems.firstValue, we are actually ripping the struct instance right out of the rangeOfFourItems storage and replacing it with another struct instance with a different firstValue.
To see that this is true, declare rangeOfFourItems with var and attach a setter observer to it, and then change rangeOfFourItems.firstValue:
struct FixedLengthRange {
var firstValue: Int
let length: Int
}
var rangeOfFourItems = FixedLengthRange(firstValue:1, length:4) {
didSet {
print("Hey, you set me!")
}
}
rangeOfFourItems.firstValue = 2 // Hey, you set me!
This shows that merely setting the property of this struct instance actually sets the struct variable itself.
But in your code, we cannot do that, because rangeOfFourItems prevents this implicit assignment - it is declared with let, meaning it must remain a constant. Thus, setting rangeOfFourItems.firstValue is prevented at compiler level.
(If FixedLengthRange were a class instead of a struct, it would be a reference type, and would be mutable in place, and setting rangeOfFourItems.firstValue would be legal even if rangeOfFourItems was declared with let.)

Xcode6 autogetters and autosetters

Xcode6 ios swift
I have created my own class and trying to make an autogetter and autosetter, but i don't really know if it's allowed.
var Birthday:NSDate {
get {return birthday}
set(newValue){birthday = newValue}
}
var BirthYear:Int32 {
get {}
set {}
}
The last part of code triggers error, missing return, so my question is that - Is there any possibility to make getter and setter without making a second variable
Stored properties in swift are backed by hidden instance variables - the property itself is its own getter and setter, unless you implement it as a computed property, in that case you have to provide your own getter and/or setter. So when you write:
var birthday: NSDate
you use it as:
let value = classInstance.birthday
to read its value, and
classInstance.birthday = someDate
to assign a new value. You don't have to do anything special to make that work.
Suggested reading: Properties
Side note: by convention variables and property should use lower camel case notation, so they should start with lowercase, and if made up of multiple words, make the first letter of each word in uppercase. For instance:
var single: Int
var multipleWordsVariable: String

let declarations require an initializer expression

I'm reading The Swift Programming Language, in the Simple Values section
“Use let to make a constant and var to make a variable. The value of a
constant doesn’t need to be known at compile time, but you must assign
it a value exactly once”
So I think I can do this
let aConstant:Int
aConstant = 5
But I get let declarations require an initializer expression !!
Why is that ? What does they mean by "The value of a constant doesn’t need to be known at compile time" ?
From the Swift Language Reference:
When a constant is declared at global scope, it must be initialized with a value.
You can only defer initialization of a constant in classes/structs, where you can choose to initialize it in the initializer of the class/struct.
The meaning of "The value of a constant doesn’t need to be known at compile time" refers to the value of the constant. In C/Objective-C a global constant needs to be assigned a value that can be computed by the compiler (usually a literal like 10 or #"Hello"). The following would not be allowed in Objective-C:
static const int foo = 10; // OK
static const int bar = calculate_bar(); // Error: Initializer element is not a compile-time constant
In Swift you don't have this restriction:
let foo = 10 // OK
let bar = calculateBar(); // OK
Edit:
The following statement in the original answer is not correct:
You can only defer initialization of a constant in classes/structs, where you can choose to initialize it in the initializer of the class/struct.
The only place where you cannot defer is in global scope (i.e. top level let expressions). While it's true that you can defer initialization in a class/struct, that's not the only place. The following is also legal for example:
func foo() {
let bar: Int
bar = 1
}
A constant does not need to be known at compile, but it must have a value after initialization:
class MyClass: NSObject {
let aConstant: Integer; // no value
init() {
aConstant = 4; // must have a value before calling super
super.init();
}
}
This allows you to set the constant to a value after it is declared and potentially unknown at compile time.
the let keyword, by definition, defines a constant.
Thus, you can't modify it once its been set.
Since thats the case, they need to be initialized when they are declared!
The solution here is to do either:
let aConstant = 5
or change it to a var
var aNonConstant:Int
aNonConstant = 5
Answer for Swift 2:
You can write constants as follows:
let aConstant:Int
aConstant = 5
Setting the type this way means: "This will be constant and it will have value when you need it". Notice that you cannot use the constant before setting value to it, there is a compile time error:
Constant 'aConstant' used before being initialized
Furthermore you can set value to aConstant only once. If you try to set value for second time, there is compile time error:
Immutable value 'aConstant' may only be initialized once
Anyway you cannot do this for global constants, there is compile time error:
Global 'let' declaration requires an initializer expression

Resources