Właśnie obejrzałem tę rozmowę Daniela Spiewaka, w której mówi on o zaletach pisania strukturalnego w porównaniu do nominalnego pisania Scali i Java . Przykładem tej różnicy może być następujący kod Java
public interface Foo {
public int length();
}
public interface Bar {
public int length();
}
Foo f = ...;
Bar b = f;
które oczywiście nie skompilowałyby się, ponieważ zgodność typu pomiędzy Foo
iBar
jest określana przez nazwę.
Z drugiej strony system typów strukturalnych może zadeklarować, że oba typy są równe lub kompatybilne, a zatem między innymi umożliwiać sprawdzanie typowania kaczek.
Teraz myślę, że rozumiem większość zalet systemu typów strukturalnych, ale zastanawiam się, czy nie unieważniłoby to bezpieczeństwa typu z przykładów takich jak poniżej
class Foo {
class Bar { /* ... */ }
def takeBar(b: Bar) = { /* ... */ }
def getBar: Bar = new Bar
}
val foo1 = new Foo
val foo2 = new Foo
foo1.takeBar(foo1.getBar) // should compile
foo1.takeBar(foo2.getBar) // should not compile
Czy dobrze rozumiem, że w systemie typu strukturalnego kompiluje się również ostatnia linia, a jeśli tak, to czy nie byłoby to niekorzystne z punktu widzenia bezpieczeństwa typu?