Java和Javascript都允許執行靜態代碼的不同方式。 Java允許您在類的主體中擁有靜態代碼,而JS允許您在類定義之外執行靜態代碼。例子:是否有可能使用Dart執行靜態代碼?
的Java:
public class MyClass {
private static Map<String,String> someMap = new HashMap<String,String();
static {
someMap.put("key1","value");
someMap.put("key2","value");
SomeOtherClass.someOtherStaticMethod();
System.out.println(someMap);
}
}
JS(基本上是一類以外的任何JS代碼):
var myint = 5;
callSomeMethod();
$(document).ready(function() {
$("#hiddenelement").hide();
});
但是,它似乎像飛鏢既支持的兩種方式。聲明全局變量和方法是受支持的,但調用方法和執行代碼就像在JS中不是。這隻能在main()
方法中完成。此外,類中的靜態代碼也是不允許的。
我知道Dart有其他的方法可以像我的第一個例子那樣靜態填充一個Map,但是還有另外一個我能想到的需要這個的例子。
讓我們考慮以下CarRegistry
實現,它允許您將汽車模型的字符串映射到相應類的實例。 F.E.當你從JSON數據車模:
class CarRegistry {
static Map<String, Function> _factoryMethods = new HashMap<String, Function>();
static void registerFactory(String key, Car factory()) {
_factoryMethods[key] = factory;
}
static Car createInstance(String key) {
Function factory = _factoryMethods[key];
if(factory != null) {
return factory();
}
throw new Exception("Key not found: $key");
}
}
class TeslaModelS extends Car {
}
class TeslaModelX extends Car {
}
爲了能夠調用CarRegistry.createInstance("teslamodelx");
,該類必須先進行登記。在Java中,可以通過將以下行添加到每個Car
類:static { CarRegistry.registerFactory("teslamodelx" ,() => new TeslaModelX()); }
來完成。你不想要的是將所有汽車硬編碼到註冊表中,因爲它將失去它作爲註冊表的功能,並且增加了耦合性。您希望能夠通過只添加一個新文件來添加新車。在JS中,您可以在類構造外調用CarRegistry.registerFactory("teslamodelx" ,() => new TeslaModelX());
行。
飛鏢怎麼能做出類似的事情?
即使您允許編輯多個文件來添加一輛新車,如果您正在編寫一個沒有main()
方法的庫,也是不可能的。那麼唯一的選擇就是在第一次調用Registry.createInstance()
方法時填寫地圖,但它不再是註冊表,那麼只是包含硬編碼汽車列表的類。
編輯:一個小除了最後一條語句我在這裏提出:填充這種登記在createInstance()
方法僅僅是一種選擇,如果註冊表在我自己的圖書館居住。如果,f.e.我想將我自己的類註冊到由我導入的不同庫提供的註冊表中,這不再是一種選擇。
就像dart-misc組提到的人一樣,我更喜歡我的庫不需要用戶調用初始化方法就可以使用。懶惰初始化方法可能在這個例子中工作,但是當我試圖將自己的類註冊到另一個庫提供的註冊表中時,這是不可能的。 –
據我所知不。 –