Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Различная семантика

// Copyright 2026 Google LLC
// SPDX-License-Identifier: Apache-2.0

use std::ffi::{CStr, c_char};
use std::time::{SystemTime, SystemTimeError, UNIX_EPOCH};

unsafe extern "C" {
    /// Создаёт отформатированное время по метке времени `t`.
    fn ctime(t: *const libc::time_t) -> *const c_char;
}

fn now_formatted() -> Result<String, SystemTimeError> {
    let now = SystemTime::now().duration_since(UNIX_EPOCH)?;
    let seconds = now.as_secs() as i64;

    // SAFETY: `seconds` генерируется системными часами и не вызовет
    // переполнения
    let ptr = unsafe { ctime(&seconds) };

    // SAFETY: ctime возвращает указатель на предварительно выделенный (ненулевой) буфер
    let ptr = unsafe { CStr::from_ptr(ptr) };

    // SAFETY: ctime использует корректный UTF-8
    let fmt = ptr.to_str().unwrap();

    Ok(fmt.trim_end().to_string())
}

fn main() {
    let t = now_formatted();
    println!("{t:?}");
}

Некоторые конструкции, которые допускают другие языки, невозможно выразить в языке Rust.

Функция ctime изменяет внутренний буфер, общий для всех вызовов. Это нельзя выразить временами жизни Rust.

  • 'static не подходит, потому что семантика другая
  • 'a не подходит, потому что буфер переживает каждый вызов