Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift中是否没有默认(T)?_Swift_Generics - Fatal编程技术网

Swift中是否没有默认(T)?

Swift中是否没有默认(T)?,swift,generics,Swift,Generics,我试图将Swift book中的矩阵示例移植为通用的 以下是我目前得到的信息: struct Matrix<T> { let rows: Int, columns: Int var grid: T[] init(rows: Int, columns: Int, repeatedValue: T) { self.rows = rows self.columns = columns grid = Array(co

我试图将Swift book中的矩阵示例移植为通用的

以下是我目前得到的信息:

struct Matrix<T> {
    let rows: Int, columns: Int
    var grid: T[]

    init(rows: Int, columns: Int, repeatedValue: T) {
        self.rows = rows
        self.columns = columns

        grid = Array(count: rows * columns, repeatedValue: repeatedValue)
    }

    func indexIsValidForRow(row: Int, column: Int) -> Bool {
        return row >= 0 && row < rows && column >= 0 && column < columns
    }

    subscript(row: Int, column: Int) -> T {
        get {
            assert(indexIsValidForRow(row, column: column), "Index out of range")
            return grid[(row * columns) + column]
        }
        set {
            assert(indexIsValidForRow(row, column: column), "Index out of range")
            grid[(row * columns) + column] = newValue
        }
    }
}
结构矩阵{ 让行:Int,列:Int 变量网格:T[] init(行:Int,列:Int,repeatedValue:T){ self.rows=行 self.columns=列 网格=数组(计数:行*列,repeatedValue:repeatedValue) } func indexIsValidForRow(行:Int,列:Int)->Bool{ 返回行>=0&&row=0&&columnT{ 得到{ 断言(indexIsValidForRow(行、列:列),“索引超出范围”) 返回网格[(行*列)+列] } 设置{ 断言(indexIsValidForRow(行、列:列),“索引超出范围”) 网格[(行*列)+列]=newValue } } } 注意,我必须将
repeatedValue:T
传递给构造函数


在C#中,我只会使用
default(T)
来表示数字,
false
表示布尔值,
null
表示引用类型。我知道Swift不允许非可选类型使用
nil
,但我仍然好奇传递显式参数是否是唯一的方法,或者我是否有一些与
default(t)
等价的方法。

没有。Swift强制您指定默认值,就像处理变量和字段一样。Swift有默认值概念的唯一情况是可选类型,它是
nil
optional.None
)。

不确定的“是”。可以使用协议约束指定泛型类或函数仅与实现默认init函数(无参数)的类型一起工作的要求。这样做的后果很可能是不好的(它不像你想象的那样工作),但它最接近你所要求的,可能比“不”的答案更接近

对我来说,我个人发现这在开发新泛型类的过程中很有帮助,然后最终我消除了约束并解决了剩余的问题。仅要求具有默认值的类型将限制泛型数据类型的用途

public protocol Defaultable
{
  init()
}

struct Matrix<Type: Defaultable>
{
  let rows: Int
  let columns: Int
  var grid: [Type]

  init(rows: Int, columns: Int)
  {
    self.rows = rows
    self.columns = columns

    grid = Array(count: rows * columns, repeatedValue: Type() )
  }
}
公共协议默认值
{
init()
}
结构矩阵
{
让行:Int
let列:Int
变量网格:[类型]
init(行:Int,列:Int)
{
self.rows=行
self.columns=列
网格=数组(计数:行*列,repeatedValue:Type())
}
}

有一种方法可以在swift中获得相当于
默认值(T)
,但它不是免费的,并且有相关的危险:

public func defaultValue<T>() -> T {
    let ptr = UnsafeMutablePointer<T>.alloc(1)
    let retval = ptr.memory
    ptr.dealloc(1)
    return retval;
}
在问题行,Swift认为
t
已经初始化,因为Swift的语义是这样说的:不能有未初始化的值类型的变量。除了因为
default
破坏了这些语义之外。执行赋值时,Swift向值见证表发出调用,以销毁现有类型。这将包括在字段
x
上调用
release
的代码,因为Swift语义表示对象的实例永远不会
nil
。然后你会遇到运行时崩溃

然而,我有理由从另一种语言与Swift进行互操作,并且我必须传入一个可选类型。不幸的是,由于种种原因(至少我还没有找到一种方法),Swift没有为我提供一种在运行时构造可选项的方法,我也无法轻松地模拟一种方法,因为可选项是根据通用枚举实现的,而枚举使用的是一种缺乏文档的5策略实现来打包枚举的负载

我通过传递一个元组来解决这个问题,我将称之为美杜莎元组,只是为了笑:
(value:T,present:Bool)
,它有一个约定,如果
present
true
,那么
value
保证有效,否则无效。我现在可以安全地使用它进行互操作:

public func toOptional<T>(optTuple: (value:T, present:Bool)) -> T? 
{
    if optTuple.present { return optTuple.value }
    else { return nil }
}

public func fromOptional<T>(opt: T?) -> (T, Bool)
{
    if opt != nil { return (opt!, true) }
    else {
        return (defaultValue(), false)
    }
}
public func to可选(optTuple:(值:T,当前值:Bool))->T?
{
如果optTuple.present{返回optTuple.value}
else{return nil}
}
public func from可选(opt:T?->(T,Bool)
{
如果opt!=nil{return(opt!,true)}
否则{
返回值(defaultValue(),false)
}
}

这样,我的调用代码以元组形式传递,而不是可选的和接收代码,并将其转换为可选的(反之亦然)。

我喜欢这种方法。我有一本有
值的字典。我提供了扩展字典,其中Value:Defaultable{…}
,我可以提供一个实现:
subscript(key:key)->Value{…}
——一个非可选的返回类型,它大大简化了使用字典的代码,并为
Dictionary
提供了我在本例中实际需要的语义。请注意,由于
repeatingValue
不是
@autoclosure
,如果
Type
是引用类型,则数组将填充相同的对象,而不是初始化为相同值的对象的副本。我认为这可能会有所帮助。
public func toOptional<T>(optTuple: (value:T, present:Bool)) -> T? 
{
    if optTuple.present { return optTuple.value }
    else { return nil }
}

public func fromOptional<T>(opt: T?) -> (T, Bool)
{
    if opt != nil { return (opt!, true) }
    else {
        return (defaultValue(), false)
    }
}