首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >迅捷的元组-不同的结构和彼此?

迅捷的元组-不同的结构和彼此?
EN

Stack Overflow用户
提问于 2014-12-09 16:40:32
回答 2查看 5.3K关注 0票数 20

元组与结构有何不同?(1)

据我所知,元组和结构都可以通过值发送,而不是通过函数调用、返回中的引用来发送,对吗?

而且,我知道如果

代码语言:javascript
复制
var A : StructureX
var B : StructureX

我知道结构A和B有相同的Type,也就是StructureX。但是..。

代码语言:javascript
复制
let A : (Int, String)
let B : (Int, String)

A和B元组是相同的Type吗?(2)使用元组而不是结构有哪些优点?(3)

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-12-09 18:48:39

我发现将Swift元组概念化为“匿名结构”是最容易的,但有一些关键的区别。它们的行为类似,但是struct有一个正式的定义,允许更多地控制可变性,而元组允许模式匹配。

元组与结构的相似性()

  • 两者都可能有任意数量的任何类型的成员,包括闭包。
  • 两者都可以内联构建(参见下面代码中的typealias )
  • 如果声明为常量,两者都可以防止任何成员的突变。
  • 如果元组有标记成员,则结构和元组都允许按标签访问成员。

元组与结构的差异()

  • 结构在使用前需要定义。
  • 结构不允许对其成员进行模式匹配。
  • 如果实例是变量,则结构允许声明为变量的成员的可变性。
  • 元组不允许更改引用其任何成员的函数或函数。
  • 元组可能不会实现协议。
  • 如果元组有匿名成员,则可以通过索引访问其成员,这与结构不同。

操场的一些代码说明了这些区别和相似之处

代码语言:javascript
复制
// All commented code causes a compilation error. Uncomment to view error messages.

struct StructureX {
    let a: Int = 0
    var b: String = "string"
}

//
// Struct member variability
//
var structureA: StructureX = StructureX()
let structureB: StructureX = StructureX()
//structureA.a = 2              // declared as a constant, instance is variable
structureA.b = "allowed"        // declared as a variable, instance is variable
//structureB.a = 2              // declared as constant, instance is constant
//structureB.b = "not allowed"  // declared as constant, instance is constant
structureA = structureB         // these are the same type
structureA


//
// A tuple can't be used as a literal to construct a struct.
//
//let StructureC: StructureX = (a: 17, b: "nope")


//
// Typealias a labeled tuple and it can be constructed similarly to a struct
//
typealias StructureT = (a: Int, b: String)
var structureD: StructureT = StructureT(a: 0, b: "asdf")
structureD
//structureD = structureA       // but they are distinct types



let emptyTuple: () = ()         // philosophically, isn't this the definition of Void?
print(emptyTuple)               // prints as ()
let single: (Int) = (23)
//let namedSingle: (a: Int) = (a: 42)


//
// Tuple Labeled Member Access
//
var labeledTupleA: (a: Int, b: String) = (a: 0, b: "string")
labeledTupleA.0 = 5
labeledTupleA.a
labeledTupleA

var check: (a: Int, b: String)
check = labeledTupleA           // same type
check

//
// Tuples can have functions/closures
//
let labeledTupleB: (Int, String, fun: () -> Void) = (0, "string", { () -> Void in
    print("hi")
})
labeledTupleB.1
labeledTupleB.fun()
//labeledTupleB.0 = 10          // this tuple is a constant, so all of its members are constant


//
// Tuples with members of the same type, but differet labels are not of the same type
//
var labeledTupleC: (c: Int, d: String) = (c: -1, d: "fail")
//labeledTupleC = labeledTupleA
//labeledTupleC = labeledTupleB


//
// Tuples with anonymous members matching the type pattern of a labeled member tuple are of equivalent type
//
var unlabeledTuple: (Int, String) = (0, "good")
unlabeledTuple = labeledTupleA
unlabeledTuple = labeledTupleC


//
// Tuples with closures may not refer to sibling members
//
var labeledTupleD: (de: Int, df: (Int) -> Void) = (de: 0, df: { (num: Int) -> Void in
    //de += num
    //self.de += num
    print(num)
})

labeledTupleD.de
labeledTupleD.df(1)


//
// Tuples allow pattern matching, Structs do not
//
//switch structureA {
//case (let i, let s):
//    print(i, s)
//default:
//    break
//}

switch labeledTupleD {
case (_, let closure):
    closure(123)
default:
    break
}
票数 23
EN

Stack Overflow用户

发布于 2014-12-09 17:47:50

我不确定元组的官方术语,但是,您可以将它们声明为一种特殊的类型:

代码语言:javascript
复制
let A : (Int, String)

也许我们可以说,A现在是一个元组类型的变量?然而,并非所有的元组都是相同的。如果您声明元组类型的变量,并尝试为它分配一个包含不同计数、序列或类型的参数的元组,您将得到一个编译器错误。这会失败的

代码语言:javascript
复制
let A : (Int, String) = ("Bob", 1234, 4.0) 

虽然这样做很好:

代码语言:javascript
复制
let A : (Int, String) = (1234, "Bob")

当然,这种强大的类型安全性也是通过结构来实现的。

就优势而言,这里有一些关于我意识到的不同之处的想法。

结构需要在使用它们之前定义它们。另一方面,元组让您返回一个任意的值列表。这有什么用?我有一个带有购物车视图控制器的iPad应用程序。在购物车视图中有一个摘要视图,它显示了购物车在任何给定时间的当前状态--有时只是普通的项目,但是RMA项目和重新订购的项目也可能在购物车中。我在购物车类上有一个方法,它返回包含购物车计数、RMA计数、重订单计数和总计数的元组。我不需要声明一个结构就可以得到所有的四个值。它非常方便:

代码语言:javascript
复制
class Cart : NSManagedObject {
    ...
    var totals : (cartCount:Int, rmaCount:Int, reorderedCount:Int, totalCount:Int) {
        let cart = ...    // Calculate cart count
        let rma = ...     // Calculate rma count
        let reorder = ... // Calculate reorder count
        let total = cart + rma + reorder // Add them all up

        return (cart, rma, reorder, total)
    }
}

在我的购物车里:

代码语言:javascript
复制
let cartValues = cart.totals
self.summaryView.cartCountLabel.text = "\(cartValues.cartCount)"       
self.summaryView.rmaCountLabel.text = "\(cartValues.rmaCount)"    
self.summaryView.reorderCountLabel.text = "\(cartValues.reorderedCount)"    
self.summaryView.totalCountLabel.text = "\(cartValues.totalCount)"

可能还有其他原因,但在这种情况下,方便是我最喜欢元组的原因。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27384151

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档