Нужен ли типобезопасный язык для статической типизации?

Я пытаюсь понять, что означает типобезопасность языка. В языке с динамической типизацией проверка типа выполняется во время выполнения, например, если я запускаю следующий PHP-код:

<?php
class MyClass
{ 
}

// Create a MyClass instance
$mc = new MyClass();

// Create an int variable
$i = 1234;

// Add $mc and $i
$result = $mc + $i;
?>

Я получу сообщение об ошибке, потому что + operator не поддерживает тип данных MyClass. Таким образом, в основном проверка типов выполнялась во время выполнения.

Означает ли безопасность типов, что проверка типа выполняется независимо от того, выполняется ли она во время компиляции или во время выполнения, или это означает, что проверка типа должна выполняться только во время компиляции, и поэтому каждой переменной должен быть явно задан тип данных (например, C , Паскаль, Java и др.).


person Community    schedule 20.01.2015    source источник
comment
Для этой конкретной ситуации существует какая-то безопасность типов, но ее нет, если вы скажете function x() { $i = 0; if (true) { $i = "bla"; } return $i; } ...   -  person Royal Bg    schedule 20.01.2015
comment
Кстати. ваш exmaple приведет к 1235, так что там тоже нет безопасности   -  person Royal Bg    schedule 20.01.2015
comment
@Royal Bg Если язык выполняет проверку типов во время выполнения и останавливает программу, если обнаружена ошибка типа, называется ли такой язык безопасным языком?   -  person    schedule 20.01.2015
comment
Скорее всего нет. В некоторых статьях вы можете найти эти языки как языки с ограниченной типобезопасностью или с типобезопасностью в ограниченном контексте. Для меня нет безопасности типов, если вы можете скрыть это в блоке if()   -  person Royal Bg    schedule 20.01.2015
comment
C не совсем типизирован. Если бы это было так, у него не было бы такого неопределенного поведения, как сейчас. C # не обязательно является статически строго типизированным, но он считается типизированным. Но опять же, этого не должно быть, если вы этого не хотите. Java была разработана как типизированная, но все же имеет ряд исключений, которые вы должны выбросить / обработать, если система типов вас подведет (BigDecimal.divide, NullPointerException, ...)   -  person Elias Van Ootegem    schedule 20.01.2015


Ответы (2)


«Типобезопасный» обычно означает «безопасный тип памяти», то есть вы не можете рассматривать память, содержащую один тип, как если бы это был другой тип.

Согласно этому определению, большинство языков более высокого уровня, включая языки с динамической типизацией, являются типобезопасными, поскольку любая попытка неправильного использования типа гарантированно вызовет в них ошибку (во время компиляции или выполнения).

Итак, безопасность типов - это в основном проблема для низкоуровневых языков, особенно C и C ++. И эти проблемы часто связаны с указателями или приведением типов (например, reinterpret_cast в C ++).

C # представляет собой интересный случай, который находится между двумя группами: он по умолчанию безопасен по типу, но вы можете отключить безопасность типов для частей вашего кода с помощью ключевого слова unsafe (обычно по соображениям производительности или взаимодействия).


Но если вы объедините безопасность типов со статической типизацией, это не обязательно означает необходимость писать типы. Многие статические языки с безопасным типом, особенно функциональные или созданные на их основе, используют вывод типов. . Это означает, что компилятор может сам определить тип переменной на основе того, что ей присвоено, поэтому вам не нужно ее вводить. Примеры этого - ключевое слово auto в C ++ и var в C #.

person svick    schedule 23.01.2015
comment
Безопасность типов не является проблемой, поскольку она предохраняет вас от ошибок и помогает убедиться, что вы знаете, что делаете (PHP похож на приготовление пищи из ингредиентов, о которых вы не знаете). И, по моему личному мнению, вывод типов в типобезопасных языках не очень хорош, так как позволяет легко потерять обзор типов переменных. А ты не знаешь? Затем человек, которому через десятилетия придется расширить или изменить ваш кодовый блок. - person Martin Braun; 02.07.2015

Ответ - нет. Python - это пример динамически, но строго типизированного языка:

>>> "foo" + 42
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: cannot concatenate 'str' and 'int' objects

Haxe - это пример языка, безопасного для типов во время компиляции, который по-прежнему не требует статического объявления типов:

class Test {
    static function main() {
        trace(10 * Test.some());
    }

    static function some() {
        return "foo";
    }
}

> Build failure
> Test.hx:3: characters 19-30 : String should be Int

Это делается с помощью вывода типа.

person georg    schedule 20.01.2015
comment
Как Haxe может знать тип данных переменной в типе компиляции, если они не объявлены статически, я могу просто изменить тип данных внутри блока if, чтобы Haxe не узнал, какой тип данных будет во время компиляции. - person ; 20.01.2015
comment
@Steve: в какой-то момент вам нужно что-то присвоить переменной, и именно здесь Haxe определяет ее тип. Вы также можете объявить переменную как динамическую, как в Python. См. old.haxe.org/ref/type_infer. - person georg; 20.01.2015
comment
Я имел в виду, что если Haxe выполняет проверку типа во время компиляции, а также поддерживает создание переменных без явного указания их типа данных, это означает, что я могу создать блок if, который изменяет тип данных переменной во время выполнения, а затем и эту переменную. используется в операторе, который не поддерживает этот недавно измененный тип данных. Например: var i = 123; если (что-то) я = новый MyClass (); var result = i + otherVariable; - person ; 20.01.2015
comment
Это похоже на статическое объявление переменных, но без фактического указания типа данных! - person ; 20.01.2015
comment
В этом случае я не думаю, что это правильное утверждение: типобезопасный язык времени компиляции, который по-прежнему не требует статического объявления типов, я не думаю, что типобезопасный язык времени компиляции может разрешить изменение типа данных во время выполнения. - person ; 20.01.2015
comment
@Steve: Может, вроде того: в C ++ есть особые приведения, например (reinterpret_cast, dynamic_cast и static_cast). В C # также есть динамическая типизация (var foo = 123; совпадает с int foo = 123;), а ключевое слово auto в C ++ 11 также допускает статические объявления без указания фактического типа. В C типы существуют только во время компиляции, поэтому вы можете легко -сортировать- изменить тип данных переменной во время выполнения: int i = 20; some_func_expecting_char_ptr(&i); ‹- в функции i будет использоваться как char *, можно использовать union, слишком - person Elias Van Ootegem; 20.01.2015