不知道如何搜索这个问题的答案,但我想知道Java,C#,Scala等编译语言是否有办法...强制编译错误,错误地使用API
假设您正在使用某种类型的API,并且您知道在调用其他方法Y之前需要调用特定的安装方法X,是否可以进行设置以使编译器捕获错误并避免必须在运行时这样做?
对于执行某些代码标准或修复损坏的API会非常有用。不知道它是否可能。
答案 0 :(得分:2)
通常,您无法在大多数静态语言中创建任意自定义编译时错误。有一些例外(例如C和C ++中的#error
指令,但即使这样,预处理器也严格地在主编译之前出现,这样做无济于事。)
但是,您可以使用专门用于在编译时捕获错误的语言功能:
要求以特定顺序调用方法对API使用者不友好,并且是高级语言中的代码味道。
一个简单的解决方案是公开一个以正确顺序执行两个操作的方法。更一般地说(例如,如果不必调用第二种方法),让第二种方法调用顶部的第一种方法。但据推测,您希望调用受API使用者的控制。
在这种情况下,重构代码,以便在不创建类型错误的情况下无法以错误的顺序调用方法。例如,假设您正在编写正则表达式库,其中必须在匹配之前编译正则表达式。在Scala中,重构:
class Regex(pattern : String) {
private[this] var compiled : Option[CompiledData] = None
def compile() {
// do stuff
this.compiled = ...
}
def search(s : String) : MatchResult = compiled match {
case Some(c) => ... // match the string
case None => throw new IllegalStateException("must compile regex first")
}
}
到
class Regex(pattern : String) {
def compile : CompiledRegex = {
// do stuff
CompiledRegex(...)
}
}
class CompiledRegex(c : CompiledData) {
def search(s : String) : MatchResult = {
... // match the string
}
}
由于search
方法现在仅在CompiledRegex
上可用,并且CompiledRegex
是通过调用Regex.compile
获得的,因此在该操作之前无法调用search
通过编译正则表达式使其有效。
此设置还有助于API使用者,因为如果用户需要MatchResult
类型的对象并且已经键入new Regex("[abc123]*")
,那么一个好的IDE可以自动完成或建议所需的方法.compile
;原始设置无法实现。
(在这个例子中,它也不再需要可变状态,这在Scala中经常被避免。)
作为替代解决方案,一些语言(我认为D和C ++ 11,虽然不是你列出的那些)支持静态断言。
答案 1 :(得分:2)
NDepend (for .NET)或JArchitect (for java)等工具可以在分析时(custom code rules over LINQ queries或warning or error)编写可以发出in the IDE的at Build Process time。例如,以下CQLinq代码规则强制要求方法调用MethodA()
时,必须调用MethodB()
:
warnif count > 0
from m in Application.Methods where
m.IsUsing("MyNamespace.MyClass.MyMethodA()") &&
!m.IsUsing("MyNamespace.MyClass.MyMethodB()")
select m
答案 2 :(得分:1)
特定函数的使用是在编译器操作之外的另一个层面...所以我不认为编译器应该做那样的事情......
另一方面:编译器通常集成到IDE中......为什么不将它也放入IDE模块中? ...大多数IDE允许预编译器操作......
您可以编写某种检查工具(基于CodeDOM或类似的东西)来测试特定的函数用法,并根据该检查结果,如果质量标准不匹配,则中止编译器运行...