Различная семантика
// 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не подходит, потому что буфер переживает каждый вызов