← Назад к вопросам

Приведи пример языков со статической типизацией

2.0 Middle🔥 181 комментариев
#Python Core

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Языки со статической типизацией — Примеры и Особенности

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

Основные языки со статической типизацией

1. Java

// Типы определяются явно и проверяются на компиляции
public class HelloWorld {
    public static void main(String[] args) {
        int age = 30;  // int — целое число
        String name = "Alice";  // String — строка
        double salary = 5000.50;  // double — число с плавающей точкой
        
        // age = "text";  // Ошибка компиляции! Нельзя присвоить String переменной int
        
        System.out.println(name + " зарабатывает " + salary);
    }
    
    // Типизация в методах
    public static int add(int a, int b) {
        return a + b;  // Должен вернуть int
    }
    
    // Полиморфизм через наследование
    public static void printData(Object obj) {
        System.out.println(obj.toString());  // Все классы наследуются от Object
    }
}

2. C++

#include <iostream>
using namespace std;

int main() {
    int age = 30;  // целое число
    double price = 99.99;  // число с плавающей точкой
    string name = "Alice";  // строка
    
    // age = "text";  // Ошибка компиляции!
    
    cout << name << " имеет возраст " << age << endl;
    
    return 0;
}

// Функции с типизацией
int multiply(int a, int b) {
    return a * b;
}

string greet(string name) {
    return "Hello, " + name;
}

// Классы с явной типизацией
class Person {
    private:
        int age;
        string name;
    
    public:
        Person(int a, string n) : age(a), name(n) {}
        
        int getAge() const {  // const означает, что метод не изменяет объект
            return age;
        }
};

3. C#

using System;

class Program {
    static void Main() {
        int number = 42;  // целое число
        string text = "Hello";  // строка
        bool isActive = true;  // логическое значение
        
        // number = "invalid";  // Ошибка компиляции!
        
        Console.WriteLine($"{text}, число: {number}");
    }
    
    // Метод с явной типизацией
    static int Add(int a, int b) {
        return a + b;
    }
    
    // Параметризованные типы (Generics)
    class Repository<T> {
        private List<T> items = new List<T>();
        
        public void Add(T item) {
            items.Add(item);
        }
        
        public T GetFirst() {
            return items[0];
        }
    }
    
    // Использование
    var userRepo = new Repository<string>();
    userRepo.Add("John");  // Только строки
    userRepo.Add(123);  // Ошибка компиляции!
}

4. TypeScript (JavaScript с типами)

// TypeScript — это надстройка над JavaScript со статической типизацией

// Примитивные типы
let age: number = 30;  // число
let name: string = "Alice";  // строка
let isActive: boolean = true;  // логическое значение
let nothing: null = null;  // null
let something: undefined = undefined;  // undefined

// age = "invalid";  // Ошибка: Type 'string' is not assignable to type 'number'

// Функции с типизацией
function add(a: number, b: number): number {
    return a + b;  // Должна вернуть number
}

function greet(name: string): string {
    return `Hello, ${name}`;
}

// Интерфейсы (Interface)
interface User {
    id: number;
    name: string;
    email: string;
    age?: number;  // Опциональное поле
}

const user: User = {
    id: 1,
    name: "Alice",
    email: "alice@example.com"
    // age опускаем, так как оно опциональное
};

// user.phone = "123456";  // Ошибка: Property 'phone' does not exist on type 'User'

// Классы с типизацией
class Person {
    private name: string;  // private — видна только внутри класса
    private age: number;
    
    constructor(name: string, age: number) {
        this.name = name;
        this.age = age;
    }
    
    public getName(): string {
        return this.name;
    }
    
    public getAge(): number {
        return this.age;
    }
}

// Обобщённые типы (Generics)
function getFirst<T>(arr: T[]): T {
    return arr[0];  // T может быть любым типом, но всегда тот же
}

const firstNumber = getFirst<number>([1, 2, 3]);  // number
const firstString = getFirst<string>(["a", "b", "c"]);  // string

// Типы объединения (Union types)
let value: number | string;  // может быть число или строка
value = 42;  // OK
value = "hello";  // OK
// value = true;  // Ошибка

// Типы пересечения (Intersection types)
interface HasName { name: string; }
interface HasAge { age: number; }

type Employee = HasName & HasAge;  // Должен иметь оба свойства
const emp: Employee = { name: "Alice", age: 30 };  // OK
// const emp2: Employee = { name: "Bob" };  // Ошибка: age отсутствует

5. Go

package main

import "fmt"

func main() {
    var age int = 30  // явная типизация
    var name string = "Alice"  // или
    salary := 5000.50  // неявная типизация, компилятор определяет double
    
    // age = "text"  // Ошибка компиляции!
    
    fmt.Println(name, "зарабатывает", salary)
}

// Функции с типизацией
func add(a int, b int) int {
    return a + b
}

// Структуры (как классы без методов)
type Person struct {
    name string
    age  int
    email string
}

// Методы привязаны к типам
func (p Person) GetAge() int {
    return p.age
}

// Интерфейсы
type Reader interface {
    Read() string
}

// Реализация интерфейса неявная
type FileReader struct {}

func (fr FileReader) Read() string {
    return "file contents"
}

6. Rust

fn main() {
    // Явная типизация
    let age: i32 = 30;  // i32 — знаковое 32-битное целое число
    let name: String = String::from("Alice");
    let salary: f64 = 5000.50;  // f64 — число с плавающей точкой
    
    // age = "text";  // Ошибка компиляции!
    
    println!("{} зарабатывает {}", name, salary);
}

// Функции с типизацией и результатом
fn add(a: i32, b: i32) -> i32 {  // -> указывает тип возвращаемого значения
    a + b
}

// Структуры
struct Person {
    name: String,
    age: i32,
}

// impl блок для методов
impl Person {
    fn new(name: String, age: i32) -> Person {
        Person { name, age }
    }
    
    fn get_age(&self) -> i32 {
        self.age
    }
}

// Обобщённые типы (Generics)
fn get_first<T>(arr: &[T]) -> Option<&T> {
    if arr.is_empty() {
        None
    } else {
        Some(&arr[0])
    }
}

// Типажи (Traits) — как интерфейсы
trait Reader {
    fn read(&self) -> String;
}

struct FileReader;

impl Reader for FileReader {
    fn read(&self) -> String {
        "file contents".to_string()
    }
}

Сравнение: Статическая vs Динамическая типизация

ХарактеристикаСтатическаяДинамическая
Когда проверяется типНа компиляцииВ runtime
Примеры языковJava, C++, TypeScript, GoPython, JavaScript, Ruby
БезопасностьОшибки найдены до запускаОшибки выявляются при выполнении
ПроизводительностьОбычно быстрееМожет быть медленнее
СинтаксисМногословен (нужно объявлять типы)Компактен
ГибкостьМенее гибкоОчень гибко
Инструменты IDEЛучше автодополнение, рефакторингХуже
Пример ошибкиjava\nint x = "text"; // Ошибка на компиляции\npython\nx = "hello"\nx = x + 5 # Ошибка на runtime\n

Python с типизацией (Type Hints)

Python изначально динамичен, но поддерживает type hints для проверки типов с помощью инструментов типа mypy:

# Type hints — подсказки типов (не проверяются автоматически!)
def add(a: int, b: int) -> int:
    return a + b

def greet(name: str) -> str:
    return f"Hello, {name}"

class User:
    def __init__(self, name: str, age: int) -> None:
        self.name = name
        self.age = age
    
    def get_info(self) -> dict[str, any]:
        return {"name": self.name, "age": self.age}

# Использование
result = add(5, 10)  # OK
result = add("hello", "world")  # Работает! Но mypy даст ошибку

# mypy проверит типы статически
# $ mypy script.py
# error: Argument 1 to "add" has incompatible type "str"; expected "int"

Преимущества статической типизации

  1. Безопасность — ошибки типов найдены до запуска
  2. Производительность — компилятор может оптимизировать
  3. IDE поддержка — автодополнение и рефакторинг
  4. Документация — типы служат документацией
  5. Масштабируемость — удобнее в больших проектах

Недостатки статической типизации

  1. Многословность — много кода на объявление типов
  2. Медленная разработка — нужно больше кода писать
  3. Меньше гибкости — сложнее быстро экспериментировать

Вывод

Выбор между статической и динамической типизацией зависит от проекта:

  • Статическая — для больших систем, критичных к надёжности (бэкенд сервисов, системное ПО)
  • Динамическая — для быстрой разработки и прототипирования (скрипты, AI/ML)