আমার নিম্নলিখিতগুলি রয়েছে:
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}" একটি আইনি নাম, নয় এটি একটি স্থানধারক অর্থ "আমি সম্পূর্ণরূপে নিশ্চিত এটা কি" নই, কিন্তু এটা হয় একটি ফ্লোটিং পয়েন্ট সংখ্যা। ভাসমান-পয়েন্ট ভেরিয়েবলের ক্ষেত্রে, আপনি যদি এটি সীমাবদ্ধ না করেন, এটি ডিফল্ট হবে f64¹ ¹ (একটি অযোগ্য পূর্ণসংখ্যার আক্ষরিক এতে ডিফল্ট হবে i32))
আরো দেখুন:
Still এখনও সংকলককে হতবাক করার উপায় রয়েছে যাতে এটি 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
ইউপিডি নিম্নলিখিতটি আর কাজ করে না। সংশোধনের জন্য শুভমের উত্তর পরীক্ষা করে দেখুন ।
চেক আউট 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 এর উত্তর ভিত্তিক এটি করতে একটি সামান্য ক্রেট লাগিয়েছি। এটি আপনাকে টাইপটি ফিরে আসতে বা মুদ্রণ করতে একটি ম্যাক্রো দেয়।
এটি আপনার কার্গো.টমল ফাইলে রাখুন:
[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)
কিছু অন্যান্য উত্তর কাজ করে না, তবে আমি পাই যে টাইপনেম ক্রেট কাজ করে।
একটি নতুন প্রকল্প তৈরি করুন:
cargo new test_typenameকার্গো.টমল সংশোধন করুন
[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)
ইন্টারেক্টিভ বিকাশের সময় যদি আপনি কেবল আপনার পরিবর্তনশীলের প্রকারটি জানতে চান তবে আমি আপনার সম্পাদক বা আদর্শের অভ্যন্তরে rls (মরিচা ভাষা সার্ভার) ব্যবহার করার পরামর্শ দেব । তারপরে আপনি কেবল স্থায়ীভাবে সক্ষম বা টানুন হোভারের ক্ষমতা এবং কেবল আপনার কার্সারটিকে ভেরিয়েবলের উপরে রেখে দিতে পারেন। একটু সংলাপে টাইপ সহ ভেরিয়েবল সম্পর্কে তথ্য উপস্থিত করা উচিত।
:?দীর্ঘদিন ধরে এখন ম্যানুয়ালি প্রয়োগ করা হয়েছে। তবে আরও বড় কথা, সংখ্যার প্রকারেরstd::fmt::Debugজন্য প্রয়োগকরণ (এর জন্য এটিই:?ব্যবহার করে) কোন ধরণের এটি বোঝাতে একটি প্রত্যয় যুক্ত করা হয় না।