你可以使用map来创建没有包装器的实例吗?

sap*_*api 3 map swift

在Python中,您可以将类的名称作为参数map,以便创建该类的实例:

class Point(object):
    def __init__(self, (x, y)):
        self.x = x
        self.y = y

coords = [(1., 2.), (3., 4.)]
pts = map(Point, coords)
Run Code Online (Sandbox Code Playgroud)

这经常被证明是一个方便的模式,所以我想在Swift中尝试相同的东西.


首先,我们建立了我们的Point课程:

import Cocoa

class Point
{
    var x: Float
    var y: Float

    init(x: Float, y: Float) {
        self.x = x
        self.y = y
    }
}

var pt = Point(x: 1, y: 2) // works fine
Run Code Online (Sandbox Code Playgroud)

但是当我们尝试使用.map创建实例时,我们会收到错误:

let coords: (Float,Float)[] = [(1, 2), (3, 4)]

// (Point).Type is not convertible to '(Float, Float) -> $T3'
var pts = coords.map(Point)
// Initializer cannot be referenced without arguments
var pts = coords.map(Point.init)
Run Code Online (Sandbox Code Playgroud)

对我来说有趣的是,如果我们首先定义一个包装函数,这确实有效:

func wrapper(x: Float, y: Float) -> Point {
    return Point(x: x, y: y)
}

// This *is* successful
var ptsWrapped = coords.map(wrapper)
Run Code Online (Sandbox Code Playgroud)

好的,现在我很好奇这是否禁止使用map方法:

extension Point {
    func newPointByAdding(x: Float, y: Float) -> Point {
        return Point(x: self.x + x, y: self.y + y)
    }
}

// This works as expected
var origin = Point(x: 0, y: 0)
var ptsAdded = coords.map(origin.newPointByAdding)
Run Code Online (Sandbox Code Playgroud)

......不,这很好.


我会很自然地承认我还没有花很多时间在swift上,所以我可能会在规范中遗漏一些禁止这个的东西.

是否可以使用map在swift中创建类/结构的新实例?

如果没有,为什么不呢?

  • 是因为init不是func吗?
  • 是否与某些上下文中不能转换为位置参数的命名参数有关?

jtb*_*des 5

Swift 2更新:

归档错误有效!

在Swift 2中,现在可以使用coords.map(Point.init):


老答案:

  • 是因为init不是一个功能?

是的.在Swift中,函数类型 "由一个参数和由箭头(->)分隔的返回类型组成",并被map定义为func map<U>(transform: (T) -> U) -> [U],即它接受一个函数.在语法中,"函数声明"和"初始化器声明"分开处理.后者没有返回类型,因为它实际上不是一个函数,只是用于初始化实例的代码块.如果你试图通过Point.init,你会得到错误"没有参数就不能引用初始化程序".

提交错误!