Swift3 Swift 2到3转换错误,类型为';[任何]';没有会员

Swift3 Swift 2到3转换错误,类型为';[任何]';没有会员,swift3,Swift3,我在Swift的2到3转换工作中遇到了一个问题,一些剩余的语法给出:“[Any]”类型的值没有成员错误 我希望有人能给我指出一个好的解决办法 Swift 2代码 Swift 2 code func search() { epsonPrinters = [Printer]() starPrinters = [Printer]() epson_startSearching() dispatch_async(dispatch_get_global_queue(D

我在Swift的2到3转换工作中遇到了一个问题,一些剩余的语法给出:“[Any]”类型的值没有成员错误

我希望有人能给我指出一个好的解决办法

Swift 2代码

Swift 2 code

func search() {

    epsonPrinters = [Printer]()
    starPrinters = [Printer]()

    epson_startSearching()

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) { [unowned self] in

        let devices = SMPort.searchPrinter()

        self.starPrinters = devices.map { portInfo -> Printer in

            let p = Printer(
                id: portInfo.modelName,
                make: "Star Micronics",
                model: portInfo.modelName,
                portName: portInfo.portName)

            if let name = portInfo.modelName as? String {
                p.emulation = name.containsString("TSP143") ? "StarGraphics" : "StarLine"
            }

            return p
        }
    }
}
Swift 3代码(我在有错误的区域上面添加了注释)

我知道我可以用以下内容替换“id:…”部分:

id: ((portInfo[0] as AnyObject).modelName) ?? "",
但这是不正确的,因为根据我们找到的打印机数量,PortInfo可以是零、1或多个

如果有人建议以一种优雅的方式对其进行重构,我将不胜感激,这是一种很好的Swift 3语法,并且很可能在Swift 4中继续存在


我正在使用Xcode 8.3.2

当您遇到一些类型错误时,最好检查每个变量的类型。当您在
let devices=…
行中选择
devices
时,Xcode的快速帮助将显示如下内容:

guard let devices = SMPort.searchPrinter() as? [PortInfo] else {
    fatalError("This may never happen")
}
func search() {

    epsonPrinters = []
    starPrinters = []

    epson_startSearching()

    DispatchQueue.global(qos: .default).async {
        guard let devices = SMPort.searchPrinter() as? [PortInfo] else {
            fatalError("This may never happen")
        }

        self.starPrinters = devices.map { portInfo -> Printer in

            let p = Printer(
                id: portInfo.modelName,
                make: "Star Micronics",
                model: portInfo.modelName,
                portName: portInfo.portName)

            if let name = portInfo.modelName {
                p.emulation = name.contains("TSP143") ? "StarGraphics" : "StarLine"
            }

            return p
        }
    }
}
声明
让设备:[任何]?

首先,它是可选的,您需要在使用实际内容之前将其展开

其次,
devices
中的元素类型是
Any
,您不能对其应用任何方法(包括属性访问器)。您需要在适当的位置将其转换为适当的类型

要解决上述两个问题,您可以这样写:

guard let devices = SMPort.searchPrinter() as? [PortInfo] else {
    fatalError("This may never happen")
}
func search() {

    epsonPrinters = []
    starPrinters = []

    epson_startSearching()

    DispatchQueue.global(qos: .default).async {
        guard let devices = SMPort.searchPrinter() as? [PortInfo] else {
            fatalError("This may never happen")
        }

        self.starPrinters = devices.map { portInfo -> Printer in

            let p = Printer(
                id: portInfo.modelName,
                make: "Star Micronics",
                model: portInfo.modelName,
                portName: portInfo.portName)

            if let name = portInfo.modelName {
                p.emulation = name.contains("TSP143") ? "StarGraphics" : "StarLine"
            }

            return p
        }
    }
}
通过上面的guard语句,“快速帮助”将向您展示:

声明
让设备:[PortInfo]

非可选的、简单的
PortInfo
数组,因此您可以对该
设备的元素使用
PortInfo
的任何方法


我会将您的Swift 2代码翻译成Swift 3,如下所示:

guard let devices = SMPort.searchPrinter() as? [PortInfo] else {
    fatalError("This may never happen")
}
func search() {

    epsonPrinters = []
    starPrinters = []

    epson_startSearching()

    DispatchQueue.global(qos: .default).async {
        guard let devices = SMPort.searchPrinter() as? [PortInfo] else {
            fatalError("This may never happen")
        }

        self.starPrinters = devices.map { portInfo -> Printer in

            let p = Printer(
                id: portInfo.modelName,
                make: "Star Micronics",
                model: portInfo.modelName,
                portName: portInfo.portName)

            if let name = portInfo.modelName {
                p.emulation = name.contains("TSP143") ? "StarGraphics" : "StarLine"
            }

            return p
        }
    }
}

您可能需要一些修复(我相信不是很多)来使用此代码,因为您没有显示所有相关内容,例如
打印机的定义

当您遇到一些类型错误时,最好检查每个变量的类型。当您在
let devices=…
行中选择
devices
时,Xcode的快速帮助将显示如下内容:

guard let devices = SMPort.searchPrinter() as? [PortInfo] else {
    fatalError("This may never happen")
}
func search() {

    epsonPrinters = []
    starPrinters = []

    epson_startSearching()

    DispatchQueue.global(qos: .default).async {
        guard let devices = SMPort.searchPrinter() as? [PortInfo] else {
            fatalError("This may never happen")
        }

        self.starPrinters = devices.map { portInfo -> Printer in

            let p = Printer(
                id: portInfo.modelName,
                make: "Star Micronics",
                model: portInfo.modelName,
                portName: portInfo.portName)

            if let name = portInfo.modelName {
                p.emulation = name.contains("TSP143") ? "StarGraphics" : "StarLine"
            }

            return p
        }
    }
}
声明
让设备:[任何]?

首先,它是可选的,您需要在使用实际内容之前将其展开

其次,
devices
中的元素类型是
Any
,您不能对其应用任何方法(包括属性访问器)。您需要在适当的位置将其转换为适当的类型

要解决上述两个问题,您可以这样写:

guard let devices = SMPort.searchPrinter() as? [PortInfo] else {
    fatalError("This may never happen")
}
func search() {

    epsonPrinters = []
    starPrinters = []

    epson_startSearching()

    DispatchQueue.global(qos: .default).async {
        guard let devices = SMPort.searchPrinter() as? [PortInfo] else {
            fatalError("This may never happen")
        }

        self.starPrinters = devices.map { portInfo -> Printer in

            let p = Printer(
                id: portInfo.modelName,
                make: "Star Micronics",
                model: portInfo.modelName,
                portName: portInfo.portName)

            if let name = portInfo.modelName {
                p.emulation = name.contains("TSP143") ? "StarGraphics" : "StarLine"
            }

            return p
        }
    }
}
通过上面的guard语句,“快速帮助”将向您展示:

声明
让设备:[PortInfo]

非可选的、简单的
PortInfo
数组,因此您可以对该
设备的元素使用
PortInfo
的任何方法


我会将您的Swift 2代码翻译成Swift 3,如下所示:

guard let devices = SMPort.searchPrinter() as? [PortInfo] else {
    fatalError("This may never happen")
}
func search() {

    epsonPrinters = []
    starPrinters = []

    epson_startSearching()

    DispatchQueue.global(qos: .default).async {
        guard let devices = SMPort.searchPrinter() as? [PortInfo] else {
            fatalError("This may never happen")
        }

        self.starPrinters = devices.map { portInfo -> Printer in

            let p = Printer(
                id: portInfo.modelName,
                make: "Star Micronics",
                model: portInfo.modelName,
                portName: portInfo.portName)

            if let name = portInfo.modelName {
                p.emulation = name.contains("TSP143") ? "StarGraphics" : "StarLine"
            }

            return p
        }
    }
}
您可能需要一些修复程序(我相信不是很多)才能使用此代码,因为您没有显示所有相关内容,例如
打印机的定义