Casts Não Tão Triviais
Por Nikita Bishonen • 1 minute read •
Casts Não Tão Triviais
Existe um lint interessante em Rust chamado trivial_casts, que na verdade não é tão trivial.
It may be possible that this will become a warning in the future
então vamos explorar alguns exemplos de código onde vou comparar:
- Casts triviais
- Definições de tipos de variáveis
- Coerção implícita
Não vou adicionar nenhum comentário, exceto as saídas do compilador, para que você possa ver as diferenças por conta própria e decidir quando e como usar casts de tipos no código Rust. Apenas direi que trivial_cast_supertype_with_shadowing parece ser um bom exemplo de como trivial_casts podem se tornar não tão triviais mesmo em um exemplo pequeno (imagina o que pode fazer em uma cadeia maior de chamadas e transformações/casts).
#![allow(dead_code)]
#![warn(trivial_casts)]
trait Polygon {}
trait TwoSidedPolygon: Polygon {}
struct Square([u32; 8]);
impl Polygon for Square {}
impl TwoSidedPolygon for Square {}
struct Triangle([u32; 6]);
impl Polygon for Triangle {}
#[cfg(test)]
mod tests {
use crate::{Polygon, Square, Triangle, TwoSidedPolygon};
#[test]
fn explicit_definition_supertype() {
let square = Square([2; 8]);
let square: &dyn Polygon = □
process(square);
// process2(square); the size for values of type `dyn Polygon` cannot be known at compilation time
// process3(square); the trait bound `dyn Polygon: TwoSidedPolygon` is not satisfied
// process_square(square); expected &Square, found &(dyn Polygon + 'static)
}
#[test]
fn explicit_definition_subtype() {
let square = Square([2; 8]);
let square: &dyn TwoSidedPolygon = □
process(square);
// process2(square); the size for values of type `dyn Polygon` cannot be known at compilation time
process3(square);
// process_square(square); expected &Square, found &(dyn TwoSidedPolygon + 'static)
}
#[test]
fn trivial_cast_supertype() {
let square = Square([2; 8]);
let square = &square as &dyn Polygon; // trivial cast: `&Square` as `&dyn Polygon`
process(square);
// process2(square); the size for values of type `dyn Polygon` cannot be known at compilation time
// process3(square); the trait bound `dyn Polygon: TwoSidedPolygon` is not satisfied
// process_square(square); expected &Square, found &dyn Polygon
}
#[test]
fn trivial_cast_subtype() {
let square = Square([2; 8]);
let square = &square as &dyn TwoSidedPolygon; // trivial cast: `&Square` as `&dyn TwoSidedPolygon`
process(square);
// process2(square); the size for values of type `dyn Polygon` cannot be known at compilation time
process3(square);
// process_square(square); expected &Square, found &(dyn TwoSidedPolygon + 'static)
}
#[test]
fn trivial_cast_struct_type() {
let square = Square([2; 8]);
let square = &square as □ // trivial cast: `&Square` as `&Square`
process(square);
process2(square);
process3(square);
process_square(square);
}
#[test]
fn auto_coercion() {
let square = Square([2; 8]);
let polygon = □
process(polygon);
process2(polygon);
process3(polygon);
process_square(polygon);
}
#[test]
fn shadowed_auto_coercion() {
let square = Square([2; 8]);
let square = Triangle([3; 6]);
let square = □
process(square);
process2(square);
// process3(square); the trait bound `Triangle: TwoSidedPolygon` is not satisfied
// process_square(square); expected &Square, found &Triangle
process_triangle(square);
}
#[test]
fn trivial_cast_supertype_with_shadowing() {
let square = Square([2; 8]);
let square = Triangle([3; 6]);
let square = &square as &dyn Polygon; // trivial cast: `&Square` as `&Square`
process(square);
// process2(square); the size for values of type `dyn Polygon` cannot be known at compilation time
// process3(square); the trait bound `dyn Polygon: TwoSidedPolygon` is not satisfied
// process_square(square); expected &Square, found &dyn Polygon
}
fn process_square(_square: &Square) {}
fn process_triangle(_triangle: &Triangle) {}
fn process(_polygon: &(impl Polygon + ?Sized)) {}
fn process2(_polygon: &impl Polygon) {}
fn process3(_polygon: &(impl TwoSidedPolygon + ?Sized)) {}
}
Comentários
Pode comentar neste artigo respondendo publicamente a este post usando uma conta Mastodon ou outra conta ActivityPub/Fediverse. Respostas não privadas conhecidas são exibidas abaixo.