【发布时间】:2017-06-06 22:46:39
【问题描述】:
我正在编写自己的类来管理 android/ios 应用程序的翻译,并且我已经生成了这段代码。我将解释下面的代码,但它非常简单和简短。
unit Localization;
interface
uses
System.Classes, System.SysUtils, Generics.Collections, Vcl.Dialogs;
//this class represents a single language (Italian, French, German...)
type
TLanguage = class
private
FTranslationList: TDictionary<string, string>;
function localize(const aWordId: string): string;
public
constructor Create;
destructor Destroy; override;
//methods
procedure addWord(const aIndex, aWord: string);
procedure removeWord(const aIndex: string);
end;
//this is a "container", it gathers all the languages in one place
type
TLocalization = class
private
FLanguagesList: TObjectList<TLanguage>;
FLocaleList: TStringList;
function getLang(Index: string): TLanguage;
public
constructor Create;
destructor Destroy; override;
//methods
function localize(const aLocaleId: string; const aIndex: string): string;
procedure addLanguage(const localeId: string);
//property to manage the languages
property Locale[Index: string]: TLanguage read getLang;
property langCount: integer read getCount;
end;
implementation
{ TLocalization }
{ add a new language to the class. }
{the localeId is a symbol like 'it' that represents the Italian language}
procedure TLocalization.addLanguage(const localeId: string);
begin
//add the language to the languages container
FLanguagesList.Add(TLanguage.Create);
//add the representation of the language.
FLocaleList.Add(localeId);
end;
constructor TLocalization.Create;
begin
FLanguagesList := TObjectList<TLanguage>.Create;
FLocaleList := TStringList.Create;
end;
destructor TLocalization.Destroy;
begin
FLanguagesList.Free;
FLocaleList.Free;
inherited;
end;
//ERROR HERE
function TLocalization.getLang(Index: string): TLanguage;
var i: integer;
begin
{ I search the locale id (for example 'it') if it's in the list. }
{ if it's in the list, I return the respective TLanguage object}
if not( FLocaleList.Find(Index, i) ) then
Result := FLanguagesList.Items[i]
else
raise Exception.Create('Locale not found');
end;
function TLocalization.localize(const aLocaleId, aIndex: string): string;
var k: integer;
begin
k := 0;
if not( FLocaleList.Find(aLocaleId, k) ) then
raise Exception.Create('Locale not found.');
//ho trovato il locale, adesso basta cercare la parola
Result := FLanguagesList.Items[k].localize(aIndex);
end;
{ TLanguage }
procedure TLanguage.addWord(const aIndex, aWord: string);
begin
FTranslationList.Add(aIndex, aWord);
end;
constructor TLanguage.Create;
begin
FTranslationList := TDictionary<string, string>.Create;
end;
destructor TLanguage.Destroy;
begin
FTranslationList.Free;
inherited;
end;
function TLanguage.localize(const aWordId: string): string;
begin
try
Result := FTranslationList.Items[aWordId];
except
Result := 'Not found.';
end;
end;
procedure TLanguage.removeWord(const aIndex: string);
begin
FTranslationList.Remove(aIndex);
end;
end.
上面的代码使用如下:
var a: TLocalization;
begin
a := TLocalization.Create;
a.addLanguage('it');
a.addLanguage('cse');
a.Locale['it'].addWord('test', 'Ciao mondo!');
a.Locale['cse'].addWord('test', 'fadfa ea!');
ButtonSomething.Text := a.localize('it', test);
end;
TLocalization 类完成所有工作。如您所见,我创建了变量a,然后向类添加了一种语言(这是在内部使用字典/字符串列表进行管理的)。
我可以使用Locale[Index: string] 属性访问我添加的语言,该属性返回一个TLanguage,我用一个类来指示单个语言。最后使用 localize 方法,我得到了我的翻译。
奇怪的是,我总是收到错误'Locale not found'。任何的想法?使用调试器我发现了这一点:
FLocaleList 有项目,但我已经对此进行了测试,我想我在第 71 行(我使用 Find 函数)做错了什么。我是否错误地传递了索引?
【问题讨论】:
-
似乎不是 .Find 你应该试试 .IndexOf ...
-
查找适用于排序列表 - 我看不到您正在这样做。使用 IndexOf 或先对列表进行排序。
-
超出了这个问题的范围 - 您似乎在课堂上混合了两个术语。区域设置和语言代码(或 ID)。您所说的区域设置通常称为语言代码(或 ID),例如
en、it等,而 locale 是一种语言的特定子类(用于世界的特定区域),例如对于英语,它可以是英式英语 (en-gb)、美式英语 (en-us) 等。因此,在翻译文本时,首先检查文本是否仅针对特定方言(区域设置)存在,如果不存在, 使用该语言常用的一种。
标签: delphi firemonkey