2009-02-09 1 views
6

사용 : 나는인터페이스에 장치를 추가하는 것은 오히려 구현보다 절을 사용 절

Unit AConsts; 
Interface 
Const 
    Const1 : WideString = 'Const1'; 
    Const2 : WideString = 'Const2'; 
    Const3 : WideString = 'Const3'; 
    Const4 = 100; 
    Const5 = 100; 
Implementation 
end. 

같은 상수로 가득 단위를 ...하고 난에서 본 기기를 사용하려면 다른 장치 사이 ...

Unit AUnit; 
Interface 
Uses 
    AConsts; 
Implementation 
end. 

Unit AUnit; 
Interface 
Implementation 
Uses 
    AConsts; 
end. 

차이가 있습니까? 다른 말로하면, 컴파일 된 앱이 문제가되는 한이 둘 사이에 차이가 있습니까?

[편집 1] 지금까지 답변

감사합니다.

나는이 질문을 충분히 명확하게하지 않았고, 나는 사과했다. 문제는 범위에 관한 것이 아니라 순환 참조를 피하는 것입니다. 컴파일 된 앱의 차이점입니다. 다른 예가 도움이 될 수 있습니다.

UnitA, UnitB 및 UnitC가 모두 AConsts를 사용하는 경우이 UnitA, UnitB 및 UnitC가 모두있는 App1간에 컴파일 된 앱에 차이가 있습니까 (AConsts 단위 및 다른 코드의 상수간에 이름 충돌이 없다고 가정). 인터페이스 섹션의 uses 절과 App2에서 작동합니다. 여기서 UnitA, UnitB 및 UnitC는 모두 Implementation 섹션의 uses 절에 AConst를가집니다.

+0

어쩌면 나는 조금 oldschool이지만 인터페이스에서는 인터페이스 밖에서 사용할 수있는 선언에 필요한 단위 만 사용해야한다고 생각합니다. 나머지는 구현에 넣어야합니다. AFAIK는 고대 시간에 컴파일러의 속도와 결과로 나오는 EXE 크기를 도왔습니다. 그러나, 그것은 여전히 ​​깔끔한 방법입니다. –

답변

10

차이점은 인터페이스 섹션에 AConsts의 내용을 참조 할 수있는 부분과 관련이 있습니다. 첫 번째 AUnit에서는 Const4을 사용하여 인터페이스 섹션에 고정 크기 배열을 선언 할 수 있습니다. Const4이 범위에 없기 때문에 두 번째 AUnit에서 그 작업을 수행 할 수 없습니다.

은주의하지 않으면 컴파일 된 프로그램에 영향을 미칩니다.

unit BConsts; 
interface 
const 
    Const4 = 50; 
implementation 
end. 

이제 우리는 다음과 같이 UnitA에 배열을 정의 :

unit AUnit 
interface 
uses BConsts; 
var 
    data: array[0..Pred(Const4)] of Integer; 
implementation 
uses AConsts; 
procedure Work; 
var 
    i: Integer; 
begin 
    for i := 0 to Const4 - 1 do begin 
    data[i] := 8; 
    end; 
end; 
end. 

그 코드의 끝을지나 쓸 것 우리가 또한Const4라는 상수를 선언 다른 장치가 있다고 가정 왜냐하면 인터페이스 섹션의 범위에있는 Const4이 구현 섹션에서 사용 된 Const4과 같지 않기 때문입니다. 이것은 상수와 함께 자주 발생하지 않습니다. 일반적으로 WindowsSysUtils에 정의 된 FindClose 함수와 GraphicsWindows에 정의 된 TBitmap 함수의 두 식별자로 발생합니다. 그리고이 두 경우에, 컴파일러는 여러분이 잘못된 것을 해냈다 고 말하지만, 두 가지 다른 의미를 가진 식별자를 사용했다는 것을 정확하게 알려주지는 않습니다. 당신은 식별자를 정규화하여 문제를 해결할 수 있습니다

위의 모든 사항이 해결됩니다, 그래서 당신의 프로그램을 컴파일하고 제대로 실행하는 경우
for i := 0 to BConsts.Const4 - 1 do 
    data[i] := 8; 

은, 그것은 단위를 사용하는 차이가 없습니다. App1과 App2를 사용하는 예제에서는 두 프로그램이 동일합니다. 그것들은 동일하지 않을 것입니다 - 컴파일러는 다른 순서로 처리 한 것들을 가지고 있으며 아마도 다른 장소에 물건을 넣을 것입니다 - 그러나 그것은 당신의 프로그램의 실행에 영향을 미치지 않을 것입니다.

1

인터페이스의 uses 문에있는 항목은 전체 장치에서 볼 수 있습니다.

구현의 uses 문에있는 항목은 구현 섹션에서만 볼 수 있습니다.

예 :

unit A; 
interface 
const 
    cA = 1; 
.. 


unit B; 
interface 
const 
    cB = 1; 
.. 



unit C; 
interface 
uses 
    A; 
const 
    cC1 = cA; 
    cC2 = cB; // Error 

implementation 
uses 
    B; 
const 
    cC3 = cA; 
    cC4 = cB; 

end. 
적어도 하나의 장치가 구현 섹션에 포함되어있는 경우 상호 의존 단위를 만들 수 있습니다

:

unit A; 
interface 
implementation 
uses 
    B; 
end. 


unit B; 
interface 
implementation 
uses 
    A; 
end. 

모두가 인터페이스 섹션에서 사용될 경우하지 않습니다 컴파일/링크.

2

IDE는 컴파일해야 할 내용을 확인하기 위해 용도를 선언하는 방법도 사용합니다.

인터페이스 섹션에서 UnitA를 사용하고 구현 섹션에서 UnitB를 사용하는 경우 유닛 B가 다시 컴파일해야하는 경우 유닛이 변경되지 않지만 unitA가 변경되면 유닛을 다시 컴파일해야합니다.

그것은 Delphis 초고속 빌드 속도의 비밀 중 하나입니다.

완성 된 실행 파일에서 선언을 넣을 때마다 링커가 똑같은 크기가 될 것으로 예상합니다 (링커는 영리하고 응용 프로그램에서 실제로 사용되는 메서드 등의 링크 만). 그러나 실제 위치는 단위 선언의 순서가 변경되면 다양한 소스가 거의 확실하게 변경됩니다.

1

순환 참조에 문제가있는 경우가 아니면 인터페이스 부분에 모든 것을 넣는 규칙을 따릅니다. 이것은 약간의 명확성을 가져 오는 데 도움이됩니다. 델파이의 일부 마법사와 "파일> 유닛 사용 ..."대화 상자는 유닛을 구현 섹션에 배치합니다.

Rob Kennedy가 강조한 범위 지정 트랩을 제외하고는 중요하지 않습니다. 표준을 세우고 그것에 충실하십시오.

3

구현 섹션에 모든 참조를 넣었고 해당 유닛 이름 만 인터페이스에 넣었습니다.

나는 가능한 한 모든 것의 범위를 제한하고 싶은데,이 정책은 그 규정에 따릅니다.

관련 문제