2011-01-29 49 views
3

當爲字符串解析創建自定義枚舉器時,我看到一些奇怪的錯誤消息。當使用記錄它提供了以下錯誤:Delphi自定義枚舉器給出奇怪的錯誤

E2010 Incompatible types: 'TSplitStringEnumerator' and 'Pointer'

當使用類(插入代碼的一些.Create電話),而不是記錄我得到一些內部錯誤不時:

有誰知道如何保持枚舉工作與記錄數據類型而不是類?

type 
    TSplitStringEnumerator = record 
     StringToParse:   string; 
     Separator:    Char; 
     S:      Integer; 
     E:      Integer; 
     L:      Integer; 
     function GetCurrent (): string; inline; 
     function MoveNext (): Boolean; inline; 
     property Current: string read GetCurrent; 
    end; 

    TSplitStringGenerator = record 
     Enum:     TSplitStringEnumerator; 
     function GetEnumerator: TSplitStringEnumerator; inline; 
    end; 

function SplitString(const StringToParse: string; Separator: Char): TSplitStringGenerator; //inline; 
begin 
    Result.Enum.StringToParse := StringToParse; 
    Result.Enum.Separator  := Separator; 
    Result.Enum.S    := 0; 
    Result.Enum.E    := 0; 
    Result.Enum.L    := Length(StringToParse); 
end; 

procedure Test(); 
var 
    S: string; 
begin 
    for S in SplitString('A;B;C', ';') do begin 
     OutputDebugString(PChar(S)); 
    end; 
end; 

{ TSplitStringGenerator } 

function TSplitStringGenerator.GetEnumerator(): TSplitStringEnumerator; 
begin 
    Result := Enum; 
end; 

{ TSplitStringEnumerator } 

function TSplitStringEnumerator.GetCurrent(): string; 
begin 
    Result := Copy(StringToParse, S, E - S); 
end; 

function TSplitStringEnumerator.MoveNext(): Boolean; 
begin 
    S := E + 1; 
    Result := S <= L; 
    E := S; 
    while (E <= L) and (StringToParse[ E ] <> Separator) do Inc(E); 
end; 

回答

4

我在QC上找到了類似的bug report #72213。該漏洞在Delphi 2010中得到修復(請參閱解析註釋)。

2

該代碼編譯,並出現在2010年德爾福爲我成功運行的輸出是:

Debug Output: A Process Project4.exe (4656) 
Debug Output: B Process Project4.exe (4656) 
Debug Output: C Process Project4.exe (4656) 

是否有可能與記錄普查員未在2007年德爾福的支持?

+0

這很有可能。代碼不能在D2009中編譯,D2009肯定支持枚舉器。另外,當你自己編寫for in循環時(雖然`x.GetEnumerator.MoveNext`用`x.GetEnumerator.Current`做了一些事情),但它確實會編譯,儘管它會陷入無限循環。還沒有到處去確定這是Ritsaert示例中的代碼還是編譯器弄亂了它。另一方面:D2009幫助清楚地表明支持使用記錄。 – 2011-01-29 17:56:53

+0

無盡循環是由GetEnumerator函數每次調用它時返回一個新的Enum成員的新初始化版本引起的?!我以爲`Result:= RecordMember`將RecordMember中的內容複製到結果中?而這樣做,當我改變了`x.GetEnumerator.Whatever`到`x.Enum.Whatever` ... – 2011-01-29 18:08:29