Swift泛型约束中的元组类型
我试图用Swift编写一个泛型函数,约束条件是参数必须是成对的序列(我将把它转换成字典)。这可能吗?我尝试了以下几种变体,但编译器不喜欢其中任何一种Swift泛型约束中的元组类型,swift,generics,tuples,Swift,Generics,Tuples,我试图用Swift编写一个泛型函数,约束条件是参数必须是成对的序列(我将把它转换成字典)。这可能吗?我尝试了以下几种变体,但编译器不喜欢其中任何一种 func foo<K, V, S: SequenceType where S.Generator.Element == (K,V)>(xs: S) { //...} func-foo(xs:S){/…} 不是对您的问题的直接回答,而是如果您想创建 然后,您可以将函数定义为扩展 方法调用字典,并使用字典定义 typealias Elem
func foo<K, V, S: SequenceType where S.Generator.Element == (K,V)>(xs: S) { //...}
func-foo(xs:S){/…}
不是对您的问题的直接回答,而是如果您想创建
然后,您可以将函数定义为扩展
方法调用字典
,并使用字典
定义
typealias Element = (Key, Value)
那么您的方法声明可以是
extension Dictionary {
func foo<S : SequenceType where S.Generator.Element == Element>(xs : S) {
//...
}
}
注意:通过上述代码中的generate()
和next()
进行枚举
是一个解决问题的方法,因为某种原因
for (key, value) in xs { }
不编译。比较一下
更新:自Swift 2/Xcode 7起,上述方法可以简化 到
扩展字典{
初始化(xs:S){
self.init()
中的xs.forEach{(键,值)
自[键]=值
}
}
}
在我看来,这像是一个编译器错误
这里的问题是:不能在泛型参数中直接使用元组类型
正如@MartinR在他的回答中所说的,如果我们使用typealias
ed元组类型,它就会起作用。但当然,我们不能在全局上下文中声明泛型typealias
例如,它编译并工作:
struct Foo<K,V> {
typealias Element = (K,V)
static func foo<S:SequenceType where S.Generator.Element == Element>(xs:S) {
var gen = xs.generate()
while let (k,v): Element = gen.next() {
println((k,v))
}
}
}
Foo.foo(["test":"foo", "bar": "baz"])
structfoo{
typealias元素=(K,V)
静态函数foo(xs:S){
var gen=xs.generate()
而let(k,v):Element=gen.next(){
println((k,v))
}
}
}
Foo.Foo([“test”:“Foo”,“bar”:“baz”])
还有一个想法是这样的:
struct SequenceOfTuple<K,V>: SequenceType {
typealias Element = (K,V)
let _generate:() -> GeneratorOf<Element>
init<S:SequenceType where S.Generator.Element == Element>(_ seq:S) {
_generate = { GeneratorOf(seq.generate()) }
}
func generate() -> GeneratorOf<Element> {
return _generate()
}
}
func foo<K,V>(xs:SequenceOfTuple<K,V>) {
for (k, v) in xs {
println((k,v))
}
}
foo(SequenceOfTuple(["test":"foo", "bar": "baz"]))
struct SequenceOfTuple:SequenceType{
typealias元素=(K,V)
让_generate:()->GeneratorOf
初始值(q:S){
_generate={GeneratorOf(seq.generate())}
}
func generate()->GeneratorOf{
返回_生成()
}
}
func-foo(xs:SequenceOfTuple){
对于xs中的(k,v){
println((k,v))
}
}
foo(SequenceOfTuple([“test”:“foo”,“bar”:“baz”]))
在这种情况下,必须使用SequenceOfTuple
type包装元组序列,然后将其传递给foo()
嗯…您可以使用带有下标的结构,并将结果存储在字典中:
struct Matrix<K:Hashable, V> {
var container:[K:[K:V]] = [:]
subscript(x:K, y:K) -> V? {
get {
return container[x]?[y]
}
set (value) {
if container[x] == nil {
container[x] = [:]
}
container[x]![y] = value
}
}
}
var matrix = Matrix<Int, String>()
matrix[11,42] = "Hello World"
println("(11,42): \(matrix[11,42])") // Optional("Hello World")
println("(1,3): \(matrix[1,3])") // nil
结构矩阵{
变量容器:[K:[K:V]]=[:]
下标(x:K,y:K)->V{
得到{
返回容器[x]?[y]
}
设置(值){
如果容器[x]==nil{
容器[x]=[:]
}
容器[x]![y]=值
}
}
}
变量矩阵=矩阵()
矩阵[11,42]=“你好,世界”
println(“(11,42):\(矩阵[11,42])”//可选(“Hello World”)
println(“(1,3):\(矩阵[1,3])”//nil
struct Foo<K,V> {
typealias Element = (K,V)
static func foo<S:SequenceType where S.Generator.Element == Element>(xs:S) {
var gen = xs.generate()
while let (k,v): Element = gen.next() {
println((k,v))
}
}
}
Foo.foo(["test":"foo", "bar": "baz"])
struct SequenceOfTuple<K,V>: SequenceType {
typealias Element = (K,V)
let _generate:() -> GeneratorOf<Element>
init<S:SequenceType where S.Generator.Element == Element>(_ seq:S) {
_generate = { GeneratorOf(seq.generate()) }
}
func generate() -> GeneratorOf<Element> {
return _generate()
}
}
func foo<K,V>(xs:SequenceOfTuple<K,V>) {
for (k, v) in xs {
println((k,v))
}
}
foo(SequenceOfTuple(["test":"foo", "bar": "baz"]))
struct Matrix<K:Hashable, V> {
var container:[K:[K:V]] = [:]
subscript(x:K, y:K) -> V? {
get {
return container[x]?[y]
}
set (value) {
if container[x] == nil {
container[x] = [:]
}
container[x]![y] = value
}
}
}
var matrix = Matrix<Int, String>()
matrix[11,42] = "Hello World"
println("(11,42): \(matrix[11,42])") // Optional("Hello World")
println("(1,3): \(matrix[1,3])") // nil