4

これに対する答えを検索する方法がわかりませんでしたが、Java、C#、Scala などのコンパイル済み言語に方法があるかどうか疑問に思っています... API が正しく使用されていない場合にコンパイラ エラーを強制する。

使用しているある種の API があり、他のメソッド Y を呼び出す前に特定のセットアップ メソッド X を呼び出す必要があることがわかっているとします。コンパイラがエラーをキャッチし、実行する必要がないようにセットアップすることは可能ですか?実行時に?

いくつかのコード標準を強制したり、壊れた API を修正したりするのにかなり役立ちます。それが可能かどうかはわかりません。

4

3 に答える 3

2

NDepend(.NETの場合)JArchitect(javaの場合)などのツールを使用すると、分析時(IDEまたはビルドプロセス時)に警告またはエラーを発行する可能性のあるLINQクエリに対してカスタムコードルールを記述できます。たとえば、次のCQLinqコードルールは、メソッドが呼び出している場合、次を呼び出す必要があることを強制します。MethodA()MethodB()

warnif count > 0 
from m in Application.Methods where
 m.IsUsing("MyNamespace.MyClass.MyMethodA()") &&
!m.IsUsing("MyNamespace.MyClass.MyMethodB()")
select m
于 2012-08-06T15:45:22.770 に答える
2

通常、ほとんどの静的言語では、任意のカスタム コンパイル時エラーを作成することはできません。いくつかの例外があります ( #errorC および C++ のディレクティブのように、プリプロセッサはメインのコンパイルの前に厳密に来るため、役に立ちません)。

ただし、コンパイル時にエラーをキャッチするように特別に設計された言語機能を利用できます。

型システムはあなたの友達です。

メソッドを特定の順序で呼び出すことを要求することは、API の利用者にとって不親切であり、高水準言語のコード臭です。

簡単な解決策は、両方の操作を正しい順序で実行する単一のメソッドを公開することです。より一般的には (たとえば、2 番目のメソッドを呼び出す必要がない場合)、2 番目のメソッドが一番上にある 1 番目のメソッドを呼び出すようにします。しかし、呼び出しを 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 だと思います) は静的アサーションをサポートしています。

于 2012-08-06T02:54:27.743 に答える
1

特定の関数の使用は、コンパイラ操作とは別のレベルで行われます...したがって、コンパイラがそのようなことを行うべきではないと思います...

一方、コンパイラは一般的にIDEに統合されています...それもIDEモジュールに入れてみませんか? ... ほとんどの IDE では、コンパイラ前の操作が許可されています ...

特定の関数の使用をテストするために、ある種のチェック ツール (CodeDOM または類似のものに基づく) を作成し、そのチェック結果に基づいて、品質基準が一致しない場合はコンパイラの実行を中止することができます ...

于 2012-08-06T02:20:15.697 に答える