How exactly does the “let” keyword work in Swift?

后端 未结 6 851
时光说笑
时光说笑 2020-12-02 23:27

I\'ve read this simple explanation in the guide:

The value of a constant doesn’t need to be known at compile time, but you must assign it a value exa

相关标签:
6条回答
  • 2020-12-02 23:42

    It's best to think of let in terms of Static Single Assignment (SSA) -- every SSA variable is assigned to exactly once. In functional languages like lisp you don't (normally) use an assignment operator -- names are bound to a value exactly once. For example, the names y and z below are bound to a value exactly once (per invocation):

    func pow(x: Float, n : Int) -> Float {
      if n == 0 {return 1}
      if n == 1 {return x}
      let y = pow(x, n/2)
      let z = y*y
      if n & 1 == 0 {
        return z
      }
      return z*x
    }
    

    This lends itself to more correct code since it enforces invariance and is side-effect free.

    Here is how an imperative-style programmer might compute the first 6 powers of 5:

    var powersOfFive = Int[]()
    for n in [1, 2, 3, 4, 5, 6] {
        var n2 = n*n
        powersOfFive += n2*n2*n
    }
    

    Obviously n2 is is a loop invariant so we could use let instead:

    var powersOfFive = Int[]()
    for n in [1, 2, 3, 4, 5, 6] {
        let n2 = n*n
        powersOfFive += n2*n2*n
    }
    

    But a truly functional programmer would avoid all the side-effects and mutations:

    let powersOfFive = [1, 2, 3, 4, 5, 6].map(
        {(num: Int) -> Int in
            let num2 = num*num
            return num2*num2*num})
    
    0 讨论(0)
  • 2020-12-02 23:46

    F# users will feel right at home with Swift's let keyword. :)

    In C# terms, you can think of "let" as "readonly var", if that construct was allowed, i.e.: an identifier that can only be bound at the point of declaration.

    0 讨论(0)
  • 2020-12-02 23:46

    Swift properties:

    Swift Properties official documentation

    In its simplest form, a stored property is a constant or variable that is stored as part of an instance of a particular class or structure. Stored properties can be either variable stored properties (introduced by the varkeyword) or constant stored properties (introduced by the let keyword).

    Example:

    The example below defines a structure called FixedLengthRange, which describes a range of integers whose range length cannot be changed once it is created:

    struct FixedLengthRange {
        var firstValue: Int
        let length: Int
    }
    

    Instances of FixedLengthRange have a variable stored property called firstValue and a constant stored property called length. In the example above, length is initialized when the new range is created and cannot be changed thereafter, because it is a constant property.

    0 讨论(0)
  • 2020-12-02 23:50

    Let


    Swift uses two basic techniques to store values for a programmer to access by using a name: let and var. Use let if you're never going to change the value associated with that name. Use var if you expect for that name to refer to a changing set of values.

    let a = 5  // This is now a constant. "a" can never be changed.
    var b = 2  // This is now a variable. Change "b" when you like.
    

    The value that a constant refers to can never be changed, however the thing that a constant refers to can change if it is an instance of a class.

    let a = 5
    let b = someClass()
    a = 6  // Nope.
    b = someOtherClass()  // Nope.
    b.setCookies( newNumberOfCookies: 5 )  // Ok, sure.
    

    Let and Collections


    When you assign an array to a constant, elements can no longer be added or removed from that array. However, the value of any of that array's elements may still be changed.

    let a = [1, 2, 3]
    a.append(4)  // This is NOT OK. You may not add a new value.
    a[0] = 0     // This is OK. You can change an existing value.
    

    A dictionary assigned to a constant can not be changed in any way.

    let a = [1: "Awesome", 2: "Not Awesome"]
    a[3] = "Bogus"             // This is NOT OK. You may not add new key:value pairs.
    a[1] = "Totally Awesome"   // This is NOT OK. You may not change a value.
    

    That is my understanding of this topic. Please correct me where needed. Excuse me if the question is already answered, I am doing this in part to help myself learn.

    0 讨论(0)
  • 2020-12-02 23:59

    let is a little bit like a const pointer in C. If you reference an object with a let, you can change the object's properties or call methods on it, but you cannot assign a different object to that identifier.

    let also has implications for collections and non-object types. If you reference a struct with a let, you cannot change its properties or call any of its mutating func methods.

    Using let/var with collections works much like mutable/immutable Foundation collections: If you assign an array to a let, you can't change its contents. If you reference a dictionary with let, you can't add/remove key/value pairs or assign a new value for a key — it's truly immutable. If you want to assign to subscripts in, append to, or otherwise mutate an array or dictionary, you must declare it with var.

    (Prior to Xcode 6 beta 3, Swift arrays had a weird mix of value and reference semantics, and were partially mutable when assigned to a let -- that's gone now.)

    0 讨论(0)
  • 2020-12-03 00:03

    First of all, "The let keyword defines a constant" is confusing for beginners who are coming from C# background (like me). After reading many Stack Overflow answers, I came to the conclusion that

    Actually, in swift there is no concept of constant

    A constant is an expression that is resolved at compilation time. For both C# and Java, constants must be assigned during declaration:

    public const double pi = 3.1416;         // C#
    public static final double pi = 3.1416   // Java
    

    Apple doc ( defining constant using "let" ):

    The value of a constant doesn’t need to be known at compile time, but you must assign the value exactly once.

    In C# terms, you can think of "let" as "readonly" variable

    Swift "let" == C# "readonly"

    0 讨论(0)
提交回复
热议问题