为一个Struct声明let但为其属性声明var之间有什么区别?反之亦然?

时间:2015-08-25 18:44:34

标签: swift functional-programming

作为主题,a和b之间有什么区别?

struct A {
  var x: Int
}
struct B {
  let x: Int
}
let a = A(x: 1)
var b = B(x: 1)

还请解释功能编程方面的影响。我应该使用哪一个为FP创建一个不可变对象?

3 个答案:

答案 0 :(得分:2)

使用a,您无法更改a.x,因为您无法通过let对值类型(例如结构)的引用进行变更。如果你说var而不是let,你可以。

使用b,您无法更改b.x,因为b.x是常量。说var在这里没关系;它是x 本身是不变的。即使B中的代码也无法更改x

答案 1 :(得分:0)

很棒的问题!

总结

a:设置完成后,无论结构内容是否可变,除了读取之外,您无法对其执行任何操作。最高级别的不变性限制了这一点。

应用程序?可能需要几次传递才能获得结构的值设置,但一旦完成,您需要将其锁定并引用不可变的完成版本。虽然我不知道如何处理结构中的可变“var”,即使它是不可变的,但这有点内存效率。

b:您只能替换结构,但无法更改结构中的值。

应用程序?设置完成后,您不希望更改该值,但是您希望以后能够完全替换该结构。

c:(请参阅下面的示例代码)您可以更改结构中的值,只要变量的类型(现在是强类型的),您就可以完全替换结构结构“C”也被键入结构“C”。这提供了最大的自由度,但可能更少的内存友好性,因为它是可变的贯穿始终。

应用程序?您希望能够更改其中的值,或者只是用另一个相同类型的结构替换整个结构。非常灵活。

希望这有帮助。

这是一些游乐场代码。

//: Playground - noun: a place where people can play


struct A {
    var x: Int
}
let a = A(x: 1)
let d = A(x: 5)



struct B {
    let x: Int
}
var b = B(x: 1)
var e = B(x: 5)




struct C {
    var x: Int
}
var c = C(x: 1)
var f = C(x: 7)


// --- A ---- /

//can we change the value of a.x?
//Nope. The "Let" for "a' locks this down.  Structure and its values are locked in
//a.x = 4

//can we replace a's value with "B" since it is the structurally similar and because it is a Var?
//Nope.  "a" is now typed to "A" and requires a structure of "A".
//a = B(x: 1)

//Can I replace "a" with exactly the same structure?
//Nope. it is assigned to a constant (let) which means the WHOLE structure is locked down.
//a = d



// --- B ---- /
//can we change the value of b.x?
//Nope.  The value in the parameter is locked down with an inner constant (let).
//b.x = 7

//can we replace b's value with "A" since it is the structurally similar and because it is a Var?
//Nope.  "b" is now strongly typed to "B" and requires a structure of "B".
//b = A(x: 1)

//Can I replace "b" with exactly the same structure?
//YES. You can change the entire value of b so long as it has a strongly typed contents of "B".
b = e


// --- C ---- /


//Can we change the value of c.x?  
//YES!  Both levels are mutable so it can be changed.
c.x = 4

//can we replace c's value with "A" since it is the structurally similar and because it is a Var?
//Nope.  "c" is still strongly typed to structure "C" and requires an identical structure.
//c = B(x: 1)


//Can I replace "C" with exactly the same structure?
//YES. You can change the entire value of "c" so long as it has a strongly typed contents of "C".
c = f

答案 2 :(得分:0)

回答问题的最后部分......

由于根据您设置结构和变量的方式存在不同的限制,最好的方法是依赖于什么是“更好”的方法,而更多地依赖于您实际需要它做什么。

当然,从效率的角度来看,Apple经常声明尽可能使用常量(let)对于内存管理更好。坦率地说,既然“a”将所有东西都锁定了,如果你想要完全有效,并且一旦你设置了包含结构的变量你就不会改变任何东西,你会想做类似下面的事情。

struct Z {
    let x: Int
}
let z = Z(x: 1)

在设置变量后,您无法执行任何操作,只需读取“z”和“a”。

因此,基于Apple的建议,“z”可能仅仅是为了内存管理而更好的做法。