আমি কীভাবে মডিউল ফাইল জুড়ে ম্যাক্রো ব্যবহার করব?


93

একই ক্রেটের মধ্যে পৃথক ফাইলে আমার দুটি মডিউল রয়েছে, যেখানে ক্রেট macro_rulesসক্ষম করেছে। আমি অন্য মডিউলে একটি মডিউলে সংজ্ঞায়িত ম্যাক্রোগুলি ব্যবহার করতে চাই।

// macros.rs
#[macro_export] // or not? is ineffectual for this, afaik
macro_rules! my_macro(...)

// something.rs
use macros;
// use macros::my_macro; <-- unresolved import (for obvious reasons)
my_macro!() // <-- how?

আমি বর্তমানে সংকলক ত্রুটিটিকে আঘাত করেছি " macro undefined: 'my_macro'" ... যা বোঝায়; ম্যাক্রো সিস্টেমটি মডিউল সিস্টেমের আগে চলে। আমি কীভাবে এটিকে ঘিরে কাজ করব?


আপনার ব্যবহার করা উচিত নয়module::my_macro!()?
u_mulder

4
নাপ (আফিক নয়) - মডিউল উপসর্গটি উপেক্ষা করা হয়েছে (সংকলক বার্তা অনুসারে)।
ব্যবহারকারী

উত্তর:


131

একই ক্রেটের মধ্যে ম্যাক্রোজ

#[macro_use]
mod foo {
    macro_rules! bar {
        () => ()
    }
}

bar!();    // works

আপনি যদি একই ক্রেটিতে ম্যাক্রোটি ব্যবহার করতে চান তবে আপনার ম্যাক্রোটি যে মডিউলটি সংজ্ঞায়িত হয়েছে তার জন্য গুণকের প্রয়োজন #[macro_use]

ম্যাক্রোগুলি কেবল তাদের সংজ্ঞায়িত করার পরে ব্যবহার করা যাবে । এর অর্থ এটি কার্যকর হয় না:

bar!();  // ERROR: cannot find macro `bar!` in this scope

#[macro_use]
mod foo {
    macro_rules! bar {
        () => ()
    }
}

ক্রেট জুড়ে ম্যাক্রো

macro_rules!অন্যান্য ক্রেটগুলি থেকে আপনার ম্যাক্রো ব্যবহার করতে , ম্যাক্রোকে নিজেই গুণকের প্রয়োজন #[macro_export]। ক্রেট আমদানি করার পরে ম্যাক্রোর মাধ্যমে আমদানি করা যায় use crate_name::macro_name;

ক্রেট util

#[macro_export]
macro_rules! foo {
    () => ()
}

ক্রেট user

use util::foo;

foo!();

নোট করুন যে ম্যাক্রো সর্বদা ক্রেটের শীর্ষ স্তরে থাকে; তাই এমনকি যদি fooএকটি ভিতরে হবে mod bar {}, userবাক্স এখনও লিখতে হবে use util::foo;এবং না use util::bar::foo;

মরিচা 2018 এর আগে আপনাকে বিবৃতিতে বৈশিষ্ট্য যুক্ত করে অন্য ক্রেটগুলি থেকে ম্যাক্রো আমদানি #[macro_use]করতে হয়েছিল extern crate util;। যা থেকে সমস্ত ম্যাক্রোগুলি আমদানি করবে util। বিকল্পভাবে, #[macro_use(cat, dog)]শুধুমাত্র ম্যাক্রোগুলি catএবং আমদানি করতে ব্যবহৃত হতে পারে dog। এই বাক্য গঠনটি আর প্রয়োজন হবে না।

ম্যাক্রোগুলির উপর দ্য রিস্ট প্রোগ্রামিং ল্যাঙ্গুয়েজ অধ্যায়টিতে আরও তথ্য পাওয়া যায় ।


27
"ম্যাক্রোগগুলি কেবলমাত্র তাদের সংজ্ঞা দেওয়ার পরে ব্যবহার করা যেতে পারে।" - এটি কী কারণ আপনি অন্যায়ভাবে সঠিকভাবে উল্লিখিত সমস্ত কাজ সম্পন্ন করেও আপনি সেই ত্রুটিটি চালিয়ে যেতে পারেন। উদাহরণস্বরূপ, যদি আপনার মডিউল থাকে macrosএবং foo(যা থেকে কোনও ম্যাক্রো ব্যবহার করে macros), এবং আপনি এগুলি আপনার lib.rs বা main.rs এ বর্ণানুক্রমিক ক্রমে তালিকাবদ্ধ করেন, ম্যাক্রোর আগে foo লোড হবে এবং কোডটি সংকলন করবে না।
neverfox

7
প্রো টিপ - এটি পুরোপুরি আমাকে পেয়েছে
semore_1267

4
এছাড়াও লক্ষ করুন যে অভ্যন্তরীণভাবে ম্যাক্রোগুলি ব্যবহারের জন্য, #[macro_use]বৈশিষ্ট্যটি প্রতিটি মডিউল এবং প্যারেন্ট মডিউল ইত্যাদিতে হওয়া উচিত until যতক্ষণ না এটি আপনার এটির প্রয়োজন যেখানে পৌঁছায়।
দশ

এই উত্তরটি আমার পক্ষে কার্যকর হয়নি। যে মডিউলটি ম্যাক্রোটিকে ঘোষণা করেছিল #[macro_use]এবং এটি lib.rs এ প্রথম ঘোষিত হয়েছিল - এখনও কার্যকর হয়নি। @ টেনের উত্তর সাহায্য করেছে এবং আমি #[macro_use]lib.rs এর শীর্ষে যুক্ত করেছি - তখন এটি কার্যকর হয়েছিল। তবে আমি এখনও নিশ্চিত নই যে সেরা অনুশীলনটি কী তা আমি এখানে পড়েছি যে "আপনি অন্য মডিউল থেকে ম্যাক্রোগুলি আমদানি করবেন না; আপনি সংজ্ঞায়িত মডিউল থেকে ম্যাক্রো রফতানি করেন"
সোরিন বলোস

আমি সর্বদা ভুলে যাই যে মরিচগুলির সাথে রাস্টের ম্যাক্রোগুলি কীভাবে কাজ করে। এটি একটি ভয়াবহ সিস্টেম, এবং আশা করি কোনও একদিন আরও ভাল হবে be
হাচ মুর

20

এই উত্তরটি মরিচা 1.1.0-স্থিতিশীল হিসাবে পুরানো।


আপনাকে #![macro_escape]শীর্ষে যুক্ত করতে macros.rsহবে mod macros;এবং ম্যাক্রো গাইডে উল্লিখিত হিসাবে এটি যুক্ত করতে হবে ।

$ cat macros.rs
#![macro_escape]

#[macro_export]
macro_rules! my_macro {
    () => { println!("hi"); }
}

$ cat something.rs
#![feature(macro_rules)]
mod macros;

fn main() {
    my_macro!();
}

$ rustc something.rs
$ ./something
hi

ভবিষ্যতের রেফারেন্সের জন্য,

$ rustc -v
rustc 0.13.0-dev (2790505c1 2014-11-03 14:17:26 +0000)

আমি এই বৈশিষ্ট্যটি পুরোপুরি মিস করতাম। ধন্যবাদ!
ব্যবহারকারীর

4
বিটিডাব্লু, #[macro_export]বৈশিষ্ট্য এখানে অপ্রয়োজনীয়। এটি কেবল তখনই প্রয়োজন যখন ম্যাক্রোটি বহিরাগত ক্রেট ব্যবহারকারীদের কাছে রফতানি করা উচিত। যদি ম্যাক্রোটি কেবল ক্রেটের অভ্যন্তরে ব্যবহৃত #[macro_export]হয় , প্রয়োজন হয় না।
ভ্লাদিমির মাত্তিভ

4
ধন্যবাদ উত্তরের জন্য অনেক। আমি কেবল যুক্ত করতে চাই, আপনার something.rsফাইলটি যদি অন্য মডিউল ব্যবহার করে, উদাহরণস্বরূপ mod foobar;, এবং এই foobarমডিউলটি ম্যাক্রোগুলি থেকে ব্যবহার করে macro.rs, তবে আপনাকে প্রোগ্রামটি সংকলনের mod macro; আগে mod foobar; রাখতে হবে। গৌণ বিষয়, তবে এটি একটি সুস্পষ্ট আইএমও নয়।
conradkleinespel

4
(এনবি এই উত্তরটি এখন পুরানো হয়েছে; আমি লুকাশ প্রদত্ত আপ-টু-ডেট উত্তর গ্রহণ করেছি)
ব্যবহারকারী

7

#![macro_use]ম্যাক্রোগুলিযুক্ত আপনার ফাইলের শীর্ষে যুক্ত করা সমস্ত ম্যাক্রোগুলিকে মূল.আরসে টানতে পারে।

উদাহরণস্বরূপ, ধরে নেওয়া যাক এই ফাইলটিকে নোড.আরএস বলা হয়:

#![macro_use]

macro_rules! test {
    () => { println!("Nuts"); }
}

macro_rules! best {
    () => { println!("Run"); }
}

pub fn fun_times() {
    println!("Is it really?");
}

আপনার মেইন.আরএসগুলি কিছু সময় নিম্নলিখিতগুলির মতো দেখাবে:

mod node;  //We're using node.rs
mod toad;  //Also using toad.rs

fn main() {
    test!();
    best!();
    toad::a_thing();
}

পরিশেষে বলা যাক যে আপনার কাছে toad.rs নামক একটি ফাইল রয়েছে যার জন্য এই ম্যাক্রোগুলিরও প্রয়োজন:

use node; //Notice this is 'use' not 'mod'

pub fn a_thing() {
  test!();

  node::fun_times();
}

লক্ষ্য করুন যে একবার ফাইলগুলি মেইনআরসগুলিতে টানা গেলে mod, আপনার বাকী ফাইলগুলি useকীওয়ার্ডের মাধ্যমে সেগুলিতে অ্যাক্সেস করতে পারে ।


আমি আরও স্পষ্টতা যোগ করেছি। Rustc 1.22.1 হিসাবে, এটি কাজ করে।
লুক ডুপিন

তুমি কি নিশ্চিত? কোথায় এটি #! [ম্যাক্রো_উজ] (# [ম্যাক্রো_স] নয়) নথিভুক্ত? আমি এটি খুঁজে পাচ্ছি না। এটি এখানে কাজ করে না।
মার্কাস

এটি পোস্ট করার সময় এটি কাজ করেছিল, জাস্টগুলির অন্তর্ভুক্ত সিস্টেমটি এমন একটি ভয়াবহ জগাখিচুড়ি, এটি সম্পূর্ণরূপে সম্ভব এটি আর কাজ করে না।
লুক ডুপিন

@Markus লক্ষ্য করুন #![macro_use]বিবৃতি ভিতরে , ম্যাক্রো-মডিউল না বাইরে। #![...]থাকার বৈশিষ্ট্যাবলী সিনট্যাক্স অনুরূপ তাদের ধারণকারী সুযোগ যেমন প্রযোজ্য #![feature(...)](স্পষ্টত এই অর্থে যদি হিসাবে লিখিত করতে হবে না #[feature(...)]এটা শব্দার্থিক ভাবে যে কম্পাইলার বদলে পুরো রুট বাক্স একটি বাক্স নির্দিষ্ট আইটেম, নির্দিষ্ট বৈশিষ্ট্য সক্রিয় করতে হবে)। সুতরাং, @ লুকডুপিন যেমন বলেছিলেন, মডিউল সিস্টেমটি একটি জগাখিচুড়ি, যদিও এটি প্রথম নজরে চেয়ে আলাদা কারণে হতে পারে।
ব্যবহারকারী

আমি এই কামনা করি যে এই উত্তরটি কীভাবে নির্মাণটি হুবহু মুখ্য নয় (যে দিকটি বাদ দিয়ে আমি উত্তরটি পছন্দ করি) mentioned এর (অ) -ডাইমোমেটিসিটি সত্ত্বেও, এটি আকর্ষণীয় কারণ এটিকে আইডেম্যাটিক ফর্মের পাশে রাখলে এটি বেদনাদায়কভাবে স্পষ্ট হয়ে যায় যে ম্যাক্রোগুলি মডিউল সিস্টেমের সাথে সাধারণ নির্মাণগুলির চেয়ে আলাদা উপায়ে যোগাযোগ করে। বা এটি কমপক্ষে একটি শক্ত গন্ধ ছেড়ে দেয় (ঠিক যেমন @ মারকাস এটির সাথে গ্রিপ রেখেছিলেন)।
ব্যবহারকারী

2

আমি মরিচা 1.44.1 এ একই সমস্যাটি দেখতে পেয়েছি এবং এই সমাধানটি পরবর্তী সংস্করণগুলির জন্য কাজ করে (মরিচা 1.7 এর জন্য কাজ করে পরিচিত)।

বলুন আপনার একটি নতুন প্রকল্প রয়েছে:

src/
    main.rs
    memory.rs
    chunk.rs

ইন main.rs , টিকা রচনার জন্য প্রয়োজন যে আপনার উৎস থেকে ম্যাক্রো ইম্পোর্ট করা হয়, অন্যথায়, এটা আপনার জন্য করে দেবে না।

#[macro_use]
mod memory;
mod chunk;

fn main() {
    println!("Hello, world!");
}

সুতরাং মেমরি.আরএস এ আপনি ম্যাক্রোগুলি সংজ্ঞায়িত করতে পারেন এবং আপনার টীকাগুলির দরকার নেই:

macro_rules! grow_capacity {
    ( $x:expr ) => {
        {
            if $x < 8 { 8 } else { $x * 2 }
        }
    };
}

অবশেষে আপনি এটি chunk.rs এ ব্যবহার করতে পারেন এবং আপনাকে এখানে ম্যাক্রো অন্তর্ভুক্ত করার দরকার নেই, কারণ এটি মূল.আরএস এ সম্পন্ন হয়েছে:

grow_capacity!(8);

সম্মত উত্তর নেই আমার জন্য বিভ্রান্তির সৃষ্ট সঙ্গে উদাহরণ দ্বারা এই ডক , এটা খুব সহায়ক হবে।


গৃহীত উত্তর আক্ষরিক আছে প্রথম কোড ব্লক প্রথম লাইন হিসাবে: #[macro_use] mod foo {
শেপমাস্টার

4
@ শিপমাস্টার এই উত্তোলিত উত্তরের একই স্থানে ম্যাক্রোর সংজ্ঞা এবং আমদানি বিবৃতি রয়েছে, সুতরাং এটি আমার জন্য বিভ্রান্তি সৃষ্টি করেছিল (আমার জন্য)। আমি #[macro_use]সংজ্ঞায় ব্যবহার করছিলাম । সংকলক বলে না যে এটি ভুল জায়গায় রয়েছে doesn't
knh190

আপনি তখন ডক্টরস্ট -আরং.আর.আর.োগ্রাট / বই / পুনরায় পড়তে ইচ্ছুক হতে পারেন ।
শেপমাস্টার

এই উত্তরের জন্য আপনাকে ধন্যবাদ! আমি গ্রহণযোগ্য উত্তরটি দ্বারাও বিভ্রান্ত হয়ে পড়েছিলাম এবং আপনার ব্যাখ্যাটি না পড়ার আগে পর্যন্ত এটিকে বুঝতে পারি না।
Prgrm.celeritas

@ শেপমাস্টার ম্যাক্রোগুলি আপনার যে বিভাগে লিঙ্ক করেছেন তাতে কীভাবে কাজ করে সে সম্পর্কে কোনও উল্লেখ নেই। আপনি কি বইয়ের অন্য কোনও অংশে লিঙ্কটি বোঝাতে চেয়েছিলেন?
অবধি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.