如何在Rust的geo_types中判断Geometry类型?解决借用与TryFrom报错
解决方案
你的问题核心在于:TryFrom<Geometry>会消耗Geometry的所有权,第一次调用Point::try_from(g)后,g已经被move,无法在后续分支中复用;而传入引用时,geo_types没有为&Geometry实现对应的TryFrom trait,解引用又会触发所有权移动错误(因为引用背后的值不能被随意move)。
下面是几种可行的修改思路:
1. 直接匹配Geometry枚举变体(推荐)
geo_types::Geometry本身是一个枚举类型,包含所有几何类型的变体,直接用match进行模式匹配是最高效、最直接的方式,完全避免所有权问题:
use geo_types::{Geometry, Point, LineString}; fn some_func(g: Geometry<f64>) { match g { Geometry::Point(_) => print!("POINT"), Geometry::LineString(_) => print!("LINESTRING"), // 可按需添加其他几何类型分支 _ => print!("UNKNOWN"), } }
如果需要使用具体的Point或LineString实例,直接在分支中解构即可:
match g { Geometry::Point(p) => println!("POINT: {:?}", p), Geometry::LineString(ls) => println!("LINESTRING: {:?}", ls), _ => print!("UNKNOWN"), }
2. 克隆Geometry(适合必须用TryFrom的场景)
如果一定要保留TryFrom的调用方式,可以通过克隆g来避免所有权移动问题,但注意这会带来额外的性能开销:
use geo_types::{Geometry, Point, LineString}; use std::convert::TryFrom; fn some_func(g: Geometry<f64>) { let g_clone = g.clone(); if let Ok(_p) = Point::try_from(g) { print!("POINT"); } else if let Ok(_ls) = LineString::try_from(g_clone) { print!("LINESTRING"); } else { print!("UNKNOWN"); } }
3. 使用引用安全的类型判断方法(适合接收引用的场景)
如果函数需要接收Geometry的引用,不想转移所有权,可以使用Geometry提供的as_*系列方法,这些方法会返回对应类型的引用(Option<&T>),无需移动所有权:
use geo_types::{Geometry, Point, LineString}; fn some_func(g: &Geometry<f64>) { if g.as_point().is_some() { print!("POINT"); } else if g.as_line_string().is_some() { print!("LINESTRING"); } else { print!("UNKNOWN"); } }
如果需要使用具体的实例引用,直接取出即可:
if let Some(p) = g.as_point() { println!("POINT coordinates: ({}, {})", p.x(), p.y()); }
内容的提问来源于stack exchange,提问作者Nino
相关产品推荐
相关产品推荐

