Я только что посмотрел этот доклад Даниэля Спевака, в котором он рассказывает о преимуществах структурной типизации по сравнению с номинальной типизацией Scala и Java . Одним из примеров этого различия будет следующий код Java
public interface Foo {
public int length();
}
public interface Bar {
public int length();
}
Foo f = ...;
Bar b = f;
который, конечно, не будет компилироваться, потому что совместимость типов между Foo
и Bar
определяется по имени.
С другой стороны, структурная система типов может объявлять оба типа равными или совместимыми и, таким образом, среди прочего, позволяет проверять типизацию утки.
Теперь я думаю, что понимаю большинство преимуществ структурной системы типов, но мне интересно, не нарушит ли она безопасность типов из примеров, подобных следующему
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
Верно ли мое понимание того, что в системе структурных типов последняя строка будет компилироваться, и если это так, не будет ли это недостатком в отношении безопасности типов?