मेरे पास निम्नलिखित हैं:
let mut my_number = 32.90;
मैं किस प्रकार का प्रिंट कर सकता हूं my_number
?
का उपयोग करना type
और type_of
काम नहीं किया। क्या कोई और तरीका है जिससे मैं नंबर का प्रकार प्रिंट कर सकता हूं?
मेरे पास निम्नलिखित हैं:
let mut my_number = 32.90;
मैं किस प्रकार का प्रिंट कर सकता हूं my_number
?
का उपयोग करना type
और type_of
काम नहीं किया। क्या कोई और तरीका है जिससे मैं नंबर का प्रकार प्रिंट कर सकता हूं?
जवाबों:
यदि आप केवल एक चर के प्रकार का पता लगाना चाहते हैं और संकलन समय पर करने को तैयार हैं, तो आप एक त्रुटि का कारण बन सकते हैं और इसे लेने के लिए संकलक प्राप्त कर सकते हैं।
उदाहरण के लिए, चर को उस प्रकार पर सेट करें जो काम नहीं करता है :
let mut my_number: () = 32.90;
// let () = x; would work too
error[E0308]: mismatched types
--> src/main.rs:2:29
|
2 | let mut my_number: () = 32.90;
| ^^^^^ expected (), found floating-point number
|
= note: expected type `()`
found type `{float}`
let mut my_number = 32.90;
my_number.what_is_this();
error[E0599]: no method named `what_is_this` found for type `{float}` in the current scope
--> src/main.rs:3:15
|
3 | my_number.what_is_this();
| ^^^^^^^^^^^^
या किसी अमान्य फ़ील्ड तक पहुँचें :
let mut my_number = 32.90;
my_number.what_is_this
error[E0610]: `{float}` is a primitive type and therefore doesn't have fields
--> src/main.rs:3:15
|
3 | my_number.what_is_this
| ^^^^^^^^^^^^
ये प्रकार को प्रकट करते हैं, जो इस मामले में वास्तव में पूरी तरह से हल नहीं हुआ है। इसे पहले उदाहरण में "फ्लोटिंग-पॉइंट वेरिएबल" कहा जाता है, और {float}
तीनों उदाहरणों में " "; यह एक आंशिक रूप से हल किया गया प्रकार है जो आपके द्वारा उपयोग किए जाने पर निर्भर करता है f32
या समाप्त हो सकता f64
है। " {float}
" एक कानूनी प्रकार का नाम नहीं है, यह एक प्लेसहोल्डर अर्थ है "मैं पूरी तरह से यकीन है कि यह क्या है" नहीं कर रहा हूँ, लेकिन यह है एक फ्लोटिंग प्वाइंट नंबर। फ़्लोटिंग-पॉइंट चर के मामले में, यदि आप इसे बाधित नहीं करते हैं, तो यह of के लिए डिफ़ॉल्ट होगा f64
। (एक अयोग्य पूर्णांक शाब्दिक डिफ़ॉल्ट होगा i32
।)
यह सभी देखें:
Iler कंपाइलर को चकरा देने के तरीके अभी भी हो सकते हैं ताकि यह f32
और के बीच तय न हो सके f64
; मुझे यकीन नहीं है। यह पहले जितना ही सरल हुआ करता था 32.90.eq(&32.90)
, लेकिन यह f64
अब दोनों के साथ व्यवहार करता है और खुशी के साथ ठगता है, इसलिए मुझे नहीं पता।
ImageBuffer<_, Vec<_>>
जो मुझे बहुत मदद नहीं करता है जब मैं एक फ़ंक्शन लिखने की कोशिश कर रहा हूं जो इन चीजों में से एक पैरामीटर के रूप में लेता है। और यह कोड में होता है जो अन्यथा तब तक संकलित करता है जब तक मैं जोड़ नहीं देता :()
। क्या कोई बेहतर तरीका नहीं है?
एक अस्थिर फ़ंक्शन है std::intrinsics::type_name
जो आपको एक प्रकार का नाम दे सकता है, हालांकि आपको रास्ट के एक रात के निर्माण का उपयोग करना होगा (यह स्थिर रस्ट में काम करने की संभावना नहीं है)। यहाँ एक उदाहरण है:
#![feature(core_intrinsics)]
fn print_type_of<T>(_: &T) {
println!("{}", unsafe { std::intrinsics::type_name::<T>() });
}
fn main() {
print_type_of(&32.90); // prints "f64"
print_type_of(&vec![1, 2, 4]); // prints "std::vec::Vec<i32>"
print_type_of(&"foo"); // prints "&str"
}
#![feature(core_intrinsics)]
print_type_of
संदर्भ ले रहा है ( &T
), मूल्य नहीं ( T
), इसलिए आपको &&str
इसके बजाय पास होना चाहिए &str
; वह यह है कि print_type_of(&"foo")
बजाय print_type_of("foo")
।
std::any::type_name
जंग के बाद से स्थिर है। 1.38: stackoverflow.com/a/58119924
आप std::any::type_name
फ़ंक्शन का उपयोग कर सकते हैं । इसके लिए रात्रिकालीन संकलक या बाहरी टोकरा की आवश्यकता नहीं है, और परिणाम काफी सही हैं:
fn print_type_of<T>(_: &T) {
println!("{}", std::any::type_name::<T>())
}
fn main() {
let s = "Hello";
let i = 42;
print_type_of(&s); // &str
print_type_of(&i); // i32
print_type_of(&main); // playground::main
print_type_of(&print_type_of::<i32>); // playground::print_type_of<i32>
print_type_of(&{ || "Hi!" }); // playground::main::{{closure}}
}
सावधान रहें: जैसा कि प्रलेखन में कहा गया है, इस जानकारी का उपयोग केवल डीबग उद्देश्य के लिए किया जाना चाहिए:
यह नैदानिक उपयोग के लिए अभिप्रेत है। स्ट्रिंग की सटीक सामग्री और प्रारूप निर्दिष्ट नहीं हैं, अन्य प्रकार के सर्वश्रेष्ठ-प्रयास विवरण होने के अलावा।
यदि आप चाहते हैं कि आपके प्रकार का प्रतिनिधित्व कंपाइलर संस्करणों के बीच समान रहे, तो आपको एक विशेषता का उपयोग करना चाहिए, जैसे कि फिकर के उत्तर में ।
यदि आप पहले से सभी प्रकार जानते हैं, तो आप एक type_of
विधि जोड़ने के लिए लक्षणों का उपयोग कर सकते हैं :
trait TypeInfo {
fn type_of(&self) -> &'static str;
}
impl TypeInfo for i32 {
fn type_of(&self) -> &'static str {
"i32"
}
}
impl TypeInfo for i64 {
fn type_of(&self) -> &'static str {
"i64"
}
}
//...
इंट्रिक्टिक्स या नथिन ', इसलिए हालांकि अधिक सीमित यह एकमात्र समाधान है यहां आपको एक स्ट्रिंग मिलती है और स्थिर है। ( फ्रेंच बोइथियोस का उत्तर देखें ) हालांकि, यह बहुत ही श्रमसाध्य है और इसमें प्रकार के मापदंडों का कोई हिसाब नहीं है, इसलिए हम कर सकते हैं ...
trait TypeInfo {
fn type_name() -> String;
fn type_of(&self) -> String;
}
macro_rules! impl_type_info {
($($name:ident$(<$($T:ident),+>)*),*) => {
$(impl_type_info_single!($name$(<$($T),*>)*);)*
};
}
macro_rules! mut_if {
($name:ident = $value:expr, $($any:expr)+) => (let mut $name = $value;);
($name:ident = $value:expr,) => (let $name = $value;);
}
macro_rules! impl_type_info_single {
($name:ident$(<$($T:ident),+>)*) => {
impl$(<$($T: TypeInfo),*>)* TypeInfo for $name$(<$($T),*>)* {
fn type_name() -> String {
mut_if!(res = String::from(stringify!($name)), $($($T)*)*);
$(
res.push('<');
$(
res.push_str(&$T::type_name());
res.push(',');
)*
res.pop();
res.push('>');
)*
res
}
fn type_of(&self) -> String {
$name$(::<$($T),*>)*::type_name()
}
}
}
}
impl<'a, T: TypeInfo + ?Sized> TypeInfo for &'a T {
fn type_name() -> String {
let mut res = String::from("&");
res.push_str(&T::type_name());
res
}
fn type_of(&self) -> String {
<&T>::type_name()
}
}
impl<'a, T: TypeInfo + ?Sized> TypeInfo for &'a mut T {
fn type_name() -> String {
let mut res = String::from("&mut ");
res.push_str(&T::type_name());
res
}
fn type_of(&self) -> String {
<&mut T>::type_name()
}
}
macro_rules! type_of {
($x:expr) => { (&$x).type_of() };
}
चलो इसका इस्तेमाल करते हैं:
impl_type_info!(i32, i64, f32, f64, str, String, Vec<T>, Result<T,S>)
fn main() {
println!("{}", type_of!(1));
println!("{}", type_of!(&1));
println!("{}", type_of!(&&1));
println!("{}", type_of!(&mut 1));
println!("{}", type_of!(&&mut 1));
println!("{}", type_of!(&mut &1));
println!("{}", type_of!(1.0));
println!("{}", type_of!("abc"));
println!("{}", type_of!(&"abc"));
println!("{}", type_of!(String::from("abc")));
println!("{}", type_of!(vec![1,2,3]));
println!("{}", <Result<String,i64>>::type_name());
println!("{}", <&i32>::type_name());
println!("{}", <&str>::type_name());
}
उत्पादन:
i32
&i32
&&i32
&mut i32
&&mut i32
&mut &i32
f64
&str
&&str
String
Vec<i32>
Result<String,i64>
&i32
&str
UPD निम्न कार्य नहीं करता है। सुधार के लिए शुभम के जवाब की जाँच करें ।
जांच करें std::intrinsics::get_tydesc<T>()
। यह अभी "प्रायोगिक" स्थिति में है, लेकिन यह ठीक है यदि आप केवल टाइप सिस्टम के आसपास हैकिंग कर रहे हैं।
निम्नलिखित उदाहरण देखें:
fn print_type_of<T>(_: &T) -> () {
let type_name =
unsafe {
(*std::intrinsics::get_tydesc::<T>()).name
};
println!("{}", type_name);
}
fn main() -> () {
let mut my_number = 32.90;
print_type_of(&my_number); // prints "f64"
print_type_of(&(vec!(1, 2, 4))); // prints "collections::vec::Vec<int>"
}
यह वही है जो प्रसिद्ध फॉर्मेटर को लागू करने के लिए आंतरिक रूप से उपयोग किया जाता है{:?}
।
** अद्यतन ** यह हाल ही में किसी भी समय काम करने के लिए सत्यापित नहीं किया गया है।
मैं एक साथ थोड़ा टोकरा यह करने के लिए vbo के जवाब के आधार पर डाल दिया। यह आपको मैक्रो को टाइप करने या वापस प्रिंट करने के लिए देता है।
इसे अपनी Cargo.toml फ़ाइल में रखें:
[dependencies]
t_bang = "0.1.2"
तो आप इसे इस तरह से उपयोग कर सकते हैं:
#[macro_use] extern crate t_bang;
use t_bang::*;
fn main() {
let x = 5;
let x_type = t!(x);
println!("{:?}", x_type); // prints out: "i32"
pt!(x); // prints out: "i32"
pt!(5); // prints out: "i32"
}
#![feature]
स्थिर रिलीज चैनल पर इस्तेमाल नहीं किया जा सकता है`
आप चर का उपयोग करने के सरल दृष्टिकोण का भी उपयोग कर सकते हैं println!("{:?}", var)
। यदि Debug
प्रकार के लिए लागू नहीं किया गया है, तो आप संकलक के त्रुटि संदेश में प्रकार देख सकते हैं:
mod some {
pub struct SomeType;
}
fn main() {
let unknown_var = some::SomeType;
println!("{:?}", unknown_var);
}
( प्लेपेन )
यह गंदा है लेकिन यह काम करता है।
Debug
इसे लागू नहीं किया गया है - हालांकि यह एक बहुत ही असंभव मामला है। सबसे पहली चीज जो आपको करनी चाहिए, वह है किसी भी स्ट्रक्चर को जोड़ना #[derive(Debug)]
। मुझे लगता है कि समय जहाँ आप नहीं चाहते Debug
हैं बहुत छोटे हैं।
println!("{:?}", unknown_var);
?? क्या यह एक स्ट्रिंग प्रक्षेप है लेकिन :?
घुंघराले कोष्ठक के अंदर क्यों है ?
Debug
क्योंकि यह लागू नहीं है, लेकिन आप भी उपयोग कर सकते हैं {}
।
वहाँ एक @ChrisMorgan है जवाब स्थिर जंग में अनुमानित प्रकार प्राप्त करने के लिए ( "फ्लोट") और वहाँ एक @ShubhamJain है इस सवाल का जवाब हर रात को जंग में अस्थिर समारोह के माध्यम से सटीक प्रकार ( "f64") प्राप्त करने के लिए।
अब यहाँ एक तरह से एक सटीक प्रकार (यानी f32 और f64 के बीच तय) स्थिर जंग में मिल सकता है:
fn main() {
let a = 5.;
let _: () = unsafe { std::mem::transmute(a) };
}
का परिणाम
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
--> main.rs:3:27
|
3 | let _: () = unsafe { std::mem::transmute(a) };
| ^^^^^^^^^^^^^^^^^^^
|
= note: source type: `f64` (64 bits)
= note: target type: `()` (0 bits)
अपडेट करें
अशांत भिन्नता
fn main() {
let a = 5.;
unsafe { std::mem::transmute::<_, ()>(a) }
}
थोड़ा कम लेकिन कुछ कम पठनीय है।
float
बता रहा है , f32
और f64
इसके साथ पूरा किया जा सकता हैstd::mem::size_of_val(&a)
यदि आपका इंटरएक्टिव विकास के दौरान आपके वैरिएबल के प्रकार को जानना चाहते हैं, तो मैं आपके संपादक या विचारक के अंदर rls (जंग भाषा सर्वर) का उपयोग करने की अत्यधिक सलाह दूंगा । आप तब स्थायी रूप से होवर क्षमता को सक्षम या टॉगल कर सकते हैं और बस चर पर अपना कर्सर रख सकते हैं। थोड़ा संवाद टाइप सहित चर के बारे में जानकारी के साथ आना चाहिए।
कुछ अन्य जवाब काम नहीं करते हैं, लेकिन मुझे लगता है कि टाइपनेम टोकरा काम करता है।
एक नया प्रोजेक्ट बनाएं:
cargo new test_typename
Cargo.toml को संशोधित करें
[dependencies]
typename = "0.1.1"
अपने स्रोत कोड को संशोधित करें
use typename::TypeName;
fn main() {
assert_eq!(String::type_name(), "std::string::String");
assert_eq!(Vec::<i32>::type_name(), "std::vec::Vec<i32>");
assert_eq!([0, 1, 2].type_name_of(), "[i32; 3]");
let a = 65u8;
let b = b'A';
let c = 65;
let d = 65i8;
let e = 65i32;
let f = 65u32;
let arr = [1,2,3,4,5];
let first = arr[0];
println!("type of a 65u8 {} is {}", a, a.type_name_of());
println!("type of b b'A' {} is {}", b, b.type_name_of());
println!("type of c 65 {} is {}", c, c.type_name_of());
println!("type of d 65i8 {} is {}", d, d.type_name_of());
println!("type of e 65i32 {} is {}", e, e.type_name_of());
println!("type of f 65u32 {} is {}", f, f.type_name_of());
println!("type of arr {:?} is {}", arr, arr.type_name_of());
println!("type of first {} is {}", first, first.type_name_of());
}
आउटपुट है:
type of a 65u8 65 is u8
type of b b'A' 65 is u8
type of c 65 65 is i32
type of d 65i8 65 is i8
type of e 65i32 65 is i32
type of f 65u32 65 is u32
type of arr [1, 2, 3, 4, 5] is [i32; 5]
type of first 1 is i32
typename
में, घोषणा में स्पष्ट प्रकार के बिना चर के साथ काम नहीं करता है। my_number
इस सवाल के साथ इसे चलाने से निम्नलिखित त्रुटि मिलती है " type_name_of
अस्पष्ट संख्यात्मक प्रकार पर कॉल नहीं कर सकता {float}
। मदद: आपको इस बंधन के लिए एक प्रकार निर्दिष्ट करना होगा, जैसे f32
"
0.65
करता हूं और यह अच्छी तरह से काम करता है type of c 0.65 0.65 is f64
:। यहाँ मेरा संस्करण है:rustc 1.38.0-nightly (69656fa4c 2019-07-13)
आप उपयोग कर सकते हैं std::any::type_name
। निम्नलिखित उन आदिम डेटा प्रकारों के उदाहरण हैं जो बिना उपयुक्त हैं &
।
use std::any::type_name;
fn type_of<T>(_: T) -> &'static str {
type_name::<T>()
}
fn main() {
let str1 = "Rust language";
let str2 = str1;
println!("str1 is: {}, and the type is {}.", str1, type_of(str1));
println!("str2 is: {}, and the type is {}.", str2, type_of(str2));
let bool1 = true;
let bool2 = bool1;
println!("bool1 is {}, and the type is {}.", bool1, type_of(bool1));
println!("bool2 is {}, and the type is {}.", bool2, type_of(bool2));
let x1 = 5;
let x2 = x1;
println!("x1 is {}, and the type is {}.", x1, type_of(x1));
println!("x2 is {}, and the type is {}.", x2, type_of(x2));
let a1 = 'a';
let a2 = a1;
println!("a1 is {}, and the type is {}.", a1, type_of(a1));
println!("a2 is {}, and the type is {}.", a2, type_of(a2));
let tup1= ("hello", 5, 'c');
let tup2 = tup1;
println!("tup1 is {:?}, and the type is {}.", tup1, type_of(tup1));
println!("tup2 is {:?}, and the type is {}.", tup2, type_of(tup2));
let array1: [i32; 3] = [0; 3];
let array2 = array1;
println!("array1 is {:?}, and the type is {}.", array1, type_of(array1));
println!("array2 is {:?}, and the type is {}.", array2, type_of(array2));
let array: [i32; 5] = [0, 1, 2, 3, 4];
let slice1 = &array[0..3];
let slice2 = slice1;
println!("slice1 is {:?}, and the type is {}.", slice1, type_of(slice1));
println!("slice2 is {:?}, and the type is {}.", slice2, type_of(slice2));
}
आउटपुट है
str1 is: Rust language, and the type is &str.
str2 is: Rust language, and the type is &str.
bool1 is true, and the type is bool.
bool2 is true, and the type is bool.
x1 is 5, and the type is i32.
x2 is 5, and the type is i32.
a1 is a, and the type is char.
a2 is a, and the type is char.
tup1 is ("hello", 5, 'c'), and the type is (&str, i32, char).
tup2 is ("hello", 5, 'c'), and the type is (&str, i32, char).
array1 is [0, 0, 0], and the type is [i32; 3].
array2 is [0, 0, 0], and the type is [i32; 3].
slice1 is [0, 1, 2], and the type is &[i32].
slice2 is [0, 1, 2], and the type is &[i32].
:?
अब काफी समय से मैन्युअल रूप से लागू किया जा रहा है। लेकिन इससे भी महत्वपूर्ण बातstd::fmt::Debug
यह है कि:?
संख्या प्रकारों के लिए कार्यान्वयन (इसके लिए जो उपयोग करता है) अब इसमें यह बताने के लिए कोई प्रत्यय शामिल नहीं है कि यह किस प्रकार का है।