【问题标题】:Using Any instead of generics使用 Any 而不是泛型
【发布时间】:2019-02-10 08:29:44
【问题描述】:

泛型 通用代码使您能够编写灵活、可重用的函数和类型,这些函数和类型可以与任何类型一起使用,但要符合您定义的要求。您可以编写避免重复并以清晰、抽象的方式表达其意图的代码。 泛型是 Swift 最强大的特性之一,而且 Swift 标准库的大部分内容都是用泛型代码构建的。事实上,您在整个语言指南中一直在使用泛型,即使您没有意识到这一点。例如,Swift 的 Array 和 Dictionary 类型都是泛型集合。您可以创建一个包含 Int 值的数组,或者一个包含 String 值的数组,或者实际上是一个可以在 Swift 中创建的任何其他类型的数组。同样,您可以创建一个字典来存储任何指定类型的值,并且该类型可以是什么没有限制。 泛型解决的问题 这是一个名为 swapTwoInts(::) 的标准非泛型函数,它交换两个 Int 值:

func swapTwoInts(_ a: inout Int, _ b: inout Int) {
   let temporaryA = a
   a = b
   b = temporaryA
}

这个函数使用 in-out 参数来交换 a 的值 和 b,如 In-Out 参数中所述。

swapTwoInts(::) 函数将 b 的原始值交换为 a, 并将 a 的原始值转换为 b。你可以调用这个函数来交换 两个 Int 变量中的值:

var someInt = 3
var anotherInt = 107
swapTwoInts(&someInt, &anotherInt)
print("someInt is now \(someInt), and anotherInt is now \(anotherInt)")

// 打印“someInt 现在是 107,anotherInt 现在是 3” swapTwoInts(::) 函数很有用,但它只能与 Int 一起使用 价值观。如果要交换两个 String 值或两个 Double 值, 您必须编写更多函数,例如 swapTwoStrings(::) 和 swapTwoDoubles(::) 函数如下所示:

func swapTwoStrings(_ a: inout String, _ b: inout String) {
    let temporaryA = a
    a = b
    b = temporaryA
}

func swapTwoDoubles(_ a: inout Double, _ b: inout Double) {
    let temporaryA = a
    a = b
    b = temporaryA
}

我的问题:

我们可以使用 Any 类型作为参数类型,而不是使用泛型函数,就像这样简单

func swapTwoInts(_a:inout Any,_b:inout Int){
   let temporaryA = a
   a = b
   b = temporaryA
}

那么如何在swift中扮演重要角色呢?

我可以写这样没有泛型的代码

var num = 3
var numtwo = 5

print(num)
print(numtwo)

func swap(_ a: inout Any, _ b: inout Any){
   let tempA=a
   a=b
   b=tempA
}

swap(a: &num, b: &numtwo) 

【问题讨论】:

  • 您的“像这样简单”的函数无法编译,也许您的意思是func swapTwoInts(_ a: inout Any,_ b: inout Any)? – 但即使那样你也不能使用它,试试var a = 1, b = 2 ; swapTwoInts(&a, &b)
  • 出现错误“无法将不可变值作为 inout 参数传递:从 'Int' 到 'Any' 的隐式转换需要临时”@MartinR
  • 请检查我编辑的问题@MartinR

标签: swift generics


【解决方案1】:

在swift中,如果变量的类型与值相同,您可以为变量赋值。所以想象一下你有这个:

var a = 1
var b = 2

func swapTwoValues(_ a: inout Any, _ b: inout Any) {
    let temporaryA = a
    a = b
    b = temporaryA
}

swapTwoValues(&a, &b) // <- Cannot pass immutable value as inout argument: implicit conversion from 'Int' to 'Any' requires a temporary

所以编译器会强制你为变量的类型隐式分配 Any。我想这不是你想要的。所以你必须告诉编译器参数的类型无关紧要。唯一重要的是它们都有 same 类型来满足编译器的需求。因此,要实现这一点,您可以使用 generic 或某种 protocol

func swapTwoValues<T>(_ a: inout T, _ b: inout T) {
    let temporaryA = a
    a = b
    b = temporaryA
}

swapTwoValues(&a, &b) // Done

提示:您可以在单行代码中将值与元组交换,而无需像这样使用temporaryVar:(即使没有函数和泛型等)

(a, b) = (b, a)

【讨论】:

  • 最后的 提示 不需要但很棒。我不知道。谢谢。
猜你喜欢
  • 2022-07-14
  • 2020-10-03
  • 2015-02-14
  • 2016-01-14
  • 1970-01-01
  • 2011-10-31
  • 1970-01-01
  • 1970-01-01
  • 2013-07-24
相关资源
最近更新 更多