无法转换类型的值' A'预期的论证类型' A'使用泛型时

时间:2016-10-20 23:41:51

标签: swift generics

我在Swift中使用泛型遇到了一个问题 - 我在Java中使用泛型,我正在努力翻译我的知识。我有一个方法,采用泛型参数类型,在协议中定义如下:

protocol Board {
    func getPlace<T : Position>(position: T) -> Place
}

我们的想法是Board可以拥有自己的Position类型,例如XYPosition SquareBoard,但六角板的位置类型不同。

然而,下面的游乐场片段有一个非常奇怪的错误:

/Users/Craig/projects/MyModule/Sources/SquareBoard.swift:16:39: error: cannot convert value of type 'XYPosition' to
 expected argument type 'XYPosition'                                                                                   
        let index = toIndex(position: position)                                                                        
                                      ^~~~~~~~                                                                         
                                               as! XYPosition

如果我试图强制施放position,它甚至会变得怪异:

/Users/Craig/projects/MyModule/Sources/SquareBoard.swift:16:48: warning: forced cast of 'XYPosition' to same type h
as no effect                                                                                                           
        let index = toIndex(position: position as! XYPosition)                                                         
                                               ^~~~~~~~~~~~~~                                                          

/Users/Craig/projects/MyModule/Sources/SquareBoard.swift:16:48: error: cannot convert value of type 'XYPosition' to
 expected argument type 'XYPosition'                                                                                   
        let index = toIndex(position: position as! XYPosition)                                                         
                                      ~~~~~~~~~^~~~~~~~~~~~~~                                                          
                                                              as! XYPosition

它是否第二次以不同的身份重新定义类型?我似乎无法确定我做错了什么。这个问题可以在下面的游乐场重现:

import Cocoa

protocol Position : Equatable {
}

struct XYPosition : Position {
    let x : Int
    let y : Int
}

func ==(lhs: XYPosition, rhs:XYPosition) -> Bool {
    return lhs.x == rhs.x && lhs.y == rhs.y
}

public class Test {

    private func toIndex(position: XYPosition) -> Int {
        return (position.y * 10) + position.x
    }

    func getPlace<XYPosition>(position: XYPosition) -> Int {
        let index = toIndex(position: position as! XYPosition)
        return 4
    }
}

1 个答案:

答案 0 :(得分:1)

由于您没有发布实际代码,因此有点令人困惑。不知道getPlace与你的问题有什么关系,我不确定你究竟想要完成什么

无论哪种方式,我都有你的游乐场工作,希望你可以在那里工作:

protocol Position : Equatable {
    var x: Int { get }
    var y: Int { get }
}

struct XYPosition : Position {
    let x : Int
    let y : Int
}

func ==(lhs: XYPosition, rhs:XYPosition) -> Bool {
    return lhs.x == rhs.x && lhs.y == rhs.y
}

public class Test {

    private func toIndex<T: Position>(position: T) -> Int {
        return (position.y * 10) + position.x
    }

    func getPlace<T: Position>(position: T) -> Int {
        let index = toIndex(position: position)
        return index
    }
}

首先,在您的原始getPlace<XYPosition>中,XYPosition是本地定义的类型,与您的结构无关,因此当您调用as! XYPosition时,您尝试将其强制转换为本地类型,而不是你的结构。

其次,我猜你误解了如何使用结构。结构不能被分类,因此您不能使用结构作为通用。只有一个协议或类。如果你传递一个结构,你可以只传递结构。