Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/117.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
Ios Swift中的合同设计_Ios_Swift_Design By Contract - Fatal编程技术网

Ios Swift中的合同设计

Ios Swift中的合同设计,ios,swift,design-by-contract,Ios,Swift,Design By Contract,Swift是否提供本地合同设计支持?我知道它可以通过断言在运行时完成,但它可以在编译时完成吗?或者,是否有任何外部插件/库可以做到这一点 编辑 我所说的“在编译时按合同进行设计”,并不是说该库将被删除。如果它像iContract为Java提供的那样,对我来说就足够了。让我们看一个例子: 使用iContract在Java中计算平方根的DBC代码可以写成: /** * @pre f >= 0.0 * @post Math.abs((return * return) - f) < 0

Swift是否提供本地合同设计支持?我知道它可以通过断言在运行时完成,但它可以在编译时完成吗?或者,是否有任何外部插件/库可以做到这一点

编辑

我所说的“在编译时按合同进行设计”,并不是说该库将被删除。如果它像iContract为Java提供的那样,对我来说就足够了。让我们看一个例子:

使用iContract在Java中计算平方根的DBC代码可以写成:

/** 
 * @pre f >= 0.0
 * @post Math.abs((return * return) - f) < 0.001 
 */ 
public float sqrt(float f) { ... } 
/**
*@pre f>=0.0
*@post-Math.abs((返回*返回)-f)<0.001
*/ 
公共浮点sqrt(浮点f){…}

现在,这使我的合同成为API规范的一部分,而不是其实现的一部分,我认为这是一种更干净的方式。打电话的人会知道自己的责任是什么,被叫人也会设定自己的期望,尽管这一切都是以更清晰的方式进行的。我们在Swift中有类似的东西吗?

我不知道这是否是您想要的,但这里有一个建议,您可以尝试一下。 如果您想定义一个协议,在该协议中可以定义sqrt函数的签名,并将实现留给其他类或结构在以后实现,您可以执行如下代码:

注意:sqrtf只是在这里使用系统实现

public protocol Math {
    func sqrtf(f: Float) -> Float
}

struct NativeMath: Math {
    func sqrtf(f: Float) -> Float {
        return sqrt(f)
    }
}


println(NativeMath().sqrtf(2))
TL;博士 正如@Tommy在您的问题下的评论中指出的,您的问题的简单明了的答案似乎是“不,编译时DbC目前不是Swift的一个特性”


现在内置了什么? 对于这种类型的设计策略的内置支持,恐怕您目前必须查看运行时。Swift目前似乎更倾向于使用运行时断言来强制执行前提条件,尽管该语言通常更强调编译时的安全性(下面将对此进行详细介绍)。全局函数
assert
assertionFailure
premission
premissionfailure
被设计为在整个代码中自由分布,而不会影响发布构建性能

当然,单元测试是检查API契约是否履行的另一种策略,但必须手动考虑和实现,因此容易出错

可能值得注意的是,在Swift 2更好的文档注释支持中,“requires”、“predition”和“postcondition”是公认的标记关键字,因此它们在快速帮助文档中显著显示:

/// - precondition: f >= 0.0
/// - postcondition: abs((return * return) - f) < 0.001
/// - returns: The square root of `f`.
func sqrt(f: Float) -> Float { ... }
//-前提条件:f>=0.0
///-后置条件:abs((返回*返回)-f)<0.001
///-返回:f的平方根。
func sqrt(f:Float)->Float{…}
那么,这种对能够为API合同提供良好文档的强调是否意味着Swift开发团队显然关心它,这是一种权宜之计,直到他们将来将某些内容纳入语法中,还是意味着他们认为此类信息属于文档?也许是毫无意义的假设。不管怎样,尽管它不是合适的DbC,但我认为它现在是一件需要注意的方便的事情


我现在能做些什么? 对于Objective-C,基本上要实现基本DbC,但是Swift中缺少宏意味着您必须求助于某种基于函数/泛型的包装器,我认为这看起来是一个非常尴尬的问题

Xcode对向目标构建阶段添加自定义脚本的支持——正如@JonShier在评论中所建议的那样——可能是最接近实用的自动DbC,而不必等待语言(可能/可能不)引入这样的功能。使用前面提到的文档标记关键字,一个分析文档注释以构建单元测试的脚本甚至可以追溯到项目中,用户只需少量的学习/努力。正如你所说,我认为这将是一个非常有趣的项目


将来它会成为内置功能吗? 目前尚不清楚本地DbC是否会在将来被纳入Swift。可以说,这是一个非常适合Swift语言任务的特性,也就是说,它促进了更安全的代码并降低了运行时错误的风险。如果它成为语言的一部分,我建议我们更可能看到它们以注释标记的形式出现,而不是以注释标记的形式出现,例如:

@contract(
    precondition = f >= 0.0,
    postcondition = abs((return * return) - f) < 0.001
)
func sqrt(f: Float) -> Float { ... } 
@合同(
前提条件=f>=0.0,
后置条件=abs((返回*返回)-f)<0.001
)
func sqrt(f:Float)->Float{…}
(但这只是猜测,目前对我们毫无用处!)


据我所知,编译时DbC可能是一个非常复杂的问题。但是谁知道呢。。。在Clang静态分析器上的工作无疑表明,有一种潜在的愿望,即将运行时错误的识别拖回编译时。也许这是一个完美的问题,可以让一个快速的静态分析器在未来工作?

有趣的问题。您所说的编译时契约式设计是什么意思?你能用另一种语言粘贴或引用一个例子吗?当然可以!查看编辑。Swift具有
预处理
预处理失败
,但它们的行为几乎类似于
断言
断言失败
。我不知道使用SwiftA脚本进行合同设计的任何方法,该脚本处理合同注释的源文件并生成等效的XCTest文件将是内置语言/IDE支持的一种方法。我担心问题的答案是“否”。但那绝对不值得50分。不,爱德华,这不是我想做的。答案与合同设计无关。你可以在这里读到这个有趣的概念,所以我想请你帮我了解更多