কোটলিনে স্থির বর্ধনের পদ্ধতি


142

কোটলিনে আপনি একটি স্থিতিশীল এক্সটেনশন পদ্ধতি কীভাবে সংজ্ঞায়িত করবেন? এটা কি সম্ভব? নীচে প্রদর্শিত হিসাবে আমার কাছে বর্তমানে একটি এক্সটেনশন পদ্ধতি রয়েছে।

public fun Uber.doMagic(context: Context) {
    // ...
}

উপরের এক্সটেনশানটি একটি উদাহরণে প্রার্থনা করা যেতে পারে।

uberInstance.doMagic(context) // Instance method

তবে আমি কীভাবে এটি নীচে দেখানো মত স্থিতিশীল পদ্ধতি তৈরি করব।

Uber.doMagic(context)         // Static or class method

1
"স্ট্যাটিক এক্সটেনশন পদ্ধতি" বলতে কী বোঝ?
আন্দ্রে ব্রেস্লাভ

3
এমন একটি পদ্ধতি যা আমি উদাহরণ ছাড়াই কল করতে পারি, তবে এটি এখনও শ্রেণীর একটি এক্সটেনশন। (নিয়মিত জাভা স্থির পদ্ধতি)
রাগুনাথ জওহর

আমি মনে করি এটি কোটলিন এক্সটেনশনগুলির উত্তম ব্যবহারের উদ্দেশ্য হতে পারে না , আমি সি # ধারণাটি বহির্ভূত করার চেষ্টা করার সময় একই জিনিসটি সম্পর্কে ভেবেছিলাম। অনুশীলনের সময় ব্যবহারটি বেশ একই রকম। কোটলিন এক্সটেনশানগুলি যখন তারা দাবি করে যে এটি স্থিতিশীলভাবে প্রেরণ করা হয়েছে, তবে এ জাতীয় জিনিস থাকলে বা দেরীতে যেমন দেরীতে আবদ্ধ থাকে সেগুলি গতিশীলভাবে "সংযুক্ত" বলে মনে হয়। যদি আমার ভুল না হয় ... বা সম্ভবত আমি এটি সম্পূর্ণ ভুল পেয়েছি :)
ড্যান

7
বর্তমানে আপনি কোনও এক্সটেনশন পদ্ধতি লিখতে পারবেন না যা শ্রেণীর উদাহরণের বিপরীতে শ্রেণীর নামে ডাকা হবে। প্রকৃতপক্ষে, এক্সটেনশন ফাংশনটি একটি রিসিভার প্যারামিটার নেয় যা একটি উদাহরণ, সুতরাং এই অংশটি এড়িয়ে যাওয়ার কোনও উপায় নেই। অন্যদিকে, আমরা শ্রেণি অবজেক্টগুলিতে এক্সটেনশন লেখার একটি পদ্ধতিতে কাজ করছি, যাতে আপনি এটি একটি শ্রেণীর নামে ডাকেন, তবে
গ্রাহকের

@ অ্যান্ড্রেব্রেস্লাভ স্থিতিশীল এক্সটেনশন ফাংশনগুলির অনুমতি দেওয়া হবে কিনা আপনি আমাদের আপডেট করতে পারেন? আমিও মিস করছি।
লার্স ব্লামবার্গ

উত্তর:


143

অর্জন Uber.doMagic(context), আপনি একটি এক্সটেনশন লিখতে পারেন সহচর বস্তুর এর Uber(সহচর বস্তুর ঘোষণা প্রয়োজন বোধ করা হয়):

class Uber {
    companion object {}
}

fun Uber.Companion.doMagic(context: Context) { }

79
এটি দুর্দান্ত তবে জাভা ক্লাস বা সহচর ছাড়া ক্লাসটি কী হবে?
জিরে

31
@ এই জাতীয় মামলার জন্য জিয়ার, কোটলিন 1.0 এ কোনও সমর্থন নেই
আন্দ্রে ব্রেস্লাভ

2
আমি আপনার ডিভিও লজিকের প্রয়োজন হলে (খালি ডেটা ক্লাসের সাথে একত্রে খনিটি বর্তমানে এটি করে) ডিফল্ট মানগুলির সাথে স্ট্রিং.ডিএফএলএফ বা ইন্টার.ডেফল্ট জাতীয় জেভিএম ফ্রেমওয়ার্ক ক্লাসগুলি প্রসারিত করার ক্ষেত্রে আমি একটি ইউজকেস দেখতে পেয়েছি।
স্টিফেন ফান্ক

36
এটা শুধুমাত্র যতদিন কাজ করে উবার একটি হল Kotlin বর্গ। এটা তোলে সম্ভাবনা স্ট্যাটিক্যালি প্রসারিত আছে ভাল হবে জাভা পাশাপাশি শ্রেণীর
kosiara - Bartosz Kosarzycki

6
এই এখনো সম্ভব আপনি এখানে দেখতে পারেন youtrack.jetbrains.com/issue/KT-11968 : এখানে একটি সংশ্লিষ্ট তাই থ্রেড নেই stackoverflow.com/questions/33911457/...
narko

12

অফিসিয়াল ডকুমেন্টেশন এটাই বলে:

কোটলিন প্যাকেজ-স্তরের কার্যকারিতার জন্য স্থিতিশীল পদ্ধতি তৈরি করে। কোটলিন নামযুক্ত বস্তু বা সহযোগী অবজেক্টগুলিতে সংজ্ঞায়িত ফাংশনগুলির জন্য স্থিতিশীল পদ্ধতিগুলিও তৈরি করতে পারে যদি আপনি @ জাভিএমস্ট্যাটিক হিসাবে এই ফাংশনগুলি বারণ করেন। উদাহরণ স্বরূপ:

কোটলিন স্থির পদ্ধতি

class C {
  companion object {
    @JvmStatic fun foo() {}
    fun bar() {}
  }
}

এখন, foo () জাভাতে স্থির, যখন বার () নয়:

C.foo(); // works fine
C.bar(); // error: not a static method

8

আমি আসলে এই সঠিক প্রশ্নটি 30 মিনিট আগে পেয়েছিলাম, তাই আমি চারপাশে খনন শুরু করেছি এবং এর কোনও সমাধান বা কোনও সমাধান খুঁজে পেলাম না, তবে অনুসন্ধানের সময় আমি কোটলিংং ওয়েবসাইটটিতে এই বিভাগটি পেয়েছি যা জানিয়েছে যে:

নোট করুন যে এক্সটেনশনগুলি একটি নালযোগ্য রিসিভার প্রকারের সাথে সংজ্ঞায়িত করা যেতে পারে। এই জাতীয় এক্সটেনশনগুলিকে কোনও অবজেক্ট ভেরিয়েবলের উপর কল করা যেতে পারে এমনকি যদি এর মানটি শূন্য থাকে।

সুতরাং তখন আমার কাছে ক্রেজিস্ট ধারণাটি ছিল, কেন কোনও নল রিসিভার (আসলে সেই রিসিভারটি ব্যবহার না করে) দিয়ে একটি এক্সটেনশন ফাংশন সংজ্ঞায়িত করা হবে না এবং তারপরে একে নাল বস্তুতে কল করুন! সুতরাং আমি এটি চেষ্টা করেছিলাম, এবং এটি বেশ ভাল কাজ করেছে, তবে এটি দেখতে খুব কুরুচিপূর্ণ ছিল। এটি এমন ছিল:

(null as Type?).staticFunction(param1, param2)

সুতরাং আমি যে রিসিভার টাইপটির আমার এক্সটেনশন ফাইলে একটি ভাল তৈরি করে নালকের মান রেখেছিলাম এবং তারপরে এটি আমার অন্যান্য শ্রেণিতে ব্যবহার করব। সুতরাং, উদাহরণ হিসাবে, এখানে আমি কীভাবে Navigationঅ্যান্ড্রয়েডে ক্লাসের জন্য "স্থিতিশীল" এক্সটেনশন ফাংশনটি প্রয়োগ করেছি : আমার নেভিগেশন এক্সটেনশনস.কেটি ফাইলে:

val SNavigation: Navigation? = null
fun Navigation?.createNavigateOnClickListener(@IdRes resId: Int, args: Bundle? = null, navOptions: NavOptions? = null,
                                                navigationExtras: Navigator.Extras? = null) : (View) -> Unit {
    //This is just implementation details, don't worry too much about them, just focus on the Navigation? part in the method declaration
    return { view: View -> view.navigate(resId, args, navOptions, navigationExtras) }
}

কোডটি এটি ব্যবহার করে:

SNavigation.createNavigateOnClickListener(R.id.action_gameWonFragment_to_gameFragment)

স্পষ্টতই, এটি কোনও শ্রেণীর নাম নয়, এটি কেবল শ্রেণীর ধরণের একটি পরিবর্তনশীল যার নাল মান রয়েছে। এটি স্পষ্টতই এক্সটেনশন প্রস্তুতকারকের দিকে (কারণ তাদের পরিবর্তনশীল তৈরি করতে হবে) এবং বিকাশকারী পক্ষের দিকে (কারণ তাদের STypeপ্রকৃত শ্রেণির নামের পরিবর্তে ফর্ম্যাটটি ব্যবহার করতে হবে), তবে এটি এখনই অর্জন করা সবচেয়ে নিকটতম প্রকৃত স্থির ফাংশনগুলির সাথে তুলনা করুন। আশা করি, কোটলিন ভাষা নির্মাতারা তৈরি করা ইস্যুতে প্রতিক্রিয়া জানাবে এবং ভাষায় সেই বৈশিষ্ট্য যুক্ত করবে।


2
হ্যাকি এটা হতে পারে। তবে চালাক শীতলও। এটি প্রশ্নের সর্বাধিক অন্তর্দৃষ্টিপূর্ণ প্রতিক্রিয়া। কোটলিন প্রথম শ্রেণীর এক্সটেনশান সরবরাহ জাল করার পক্ষে যথাসাধ্য চেষ্টা করছে, তাই আইএমও, আপনি এর অদম্যতা মোকাবেলায় সেরা-আপনি পারেন এমন সমাধান ব্যবহার করেন। খুশী হলাম।
ট্র্যাভিস গ্রিগস

5

আপনি কম্পিয়েন অবজেক্ট ব্যবহার করে একটি স্থিতিশীল পদ্ধতি তৈরি করতে পারেন:

class Foo {
    // ...
    companion object {
        public fun bar() {
            // do anything
        }
    }
}

এবং তারপরে আপনি এটিকে কল করতে পারেন:

class Baz {
    // ...
    private fun callBar() {
        Foo.bar()
    }
}

আমি বিশ্বাস করি এটি আসলে অচল নয়। সহযোগী বস্তুগুলি আপনাকে ক্লাসের নাম ব্যবহার করে কল করার অনুমতি দেয়, তবে এখনও শ্রেণীর উদাহরণ ব্যবহার করে। এছাড়াও, প্রশ্নটি স্থির ক্রিয়াকলাপ নয়, স্থির ক্রিয়াকলাপ সম্পর্কে ছিল। তবে স্ট্যাটিক ফাংশন থাকলে আপনি platformStaticটীকাটি ব্যবহার করতে পারেন ।
রাগুনাথ জওহর

1
platformStaticJvmStaticবর্তমান কোটলিনে নতুন নামকরণ করা হয়েছিল ।
জেইসন মিনার্ড

0

এই লিঙ্কটি দেখার জন্য আপনাকে পুনরুদ্ধার করুন। আপনি সেখানে দেখতে পাচ্ছেন, আপনার কেবল প্যাকেজ (ফাইল) এর শীর্ষ স্তরে পদ্ধতি ঘোষণা করা উচিত:

package strings
public fun joinToString(...): String { ... }

এটি সমান

package strings;

public class JoinKt {
    public static String joinToString(...) { ... }
}

কনস্ট্যান্সের সাথে সবকিছু একই রকম। এই ঘোষণা

val UNIX_LINE_SEPARATOR = "\n"

সমান

public static final String UNIX_LINE_SEPARATOR = "\n";

-3

আমিও কোটলিনে স্থির এক্সটেনশন পদ্ধতি যুক্ত করার সম্ভাবনা থাকার খুব পছন্দ করি। এখনকার মতো কাজ হিসাবে আমি এগুলির সবগুলিতে একটি স্থিতিশীল এক্সটেনশন পদ্ধতি ব্যবহার না করে একাধিক ক্লাসে এক্সটেনশন পদ্ধতি যুক্ত করছি।

class Util    

fun Util.isDeviceOnline(context: Context): Boolean {
    val connMgr = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
    val networkInfo = connMgr.activeNetworkInfo
    return networkInfo != null && networkInfo.isConnected
}

fun Activity.isDeviceOnline(context: Context) = { Util().isDeviceOnline(context) }
fun OkHttpClient.isDeviceOnline(context: Context) = { Util().isDeviceOnline(context) }

2
মূল প্রশ্নটি ছিল একটি স্ট্যাটিক পদ্ধতিতে কীভাবে জাভাস ক্লাস বাড়ানো যায় । আপনার ক্ষেত্রে, এর অর্থ Activity.isDeviceOnline(...)একটি উদাহরণ ছাড়াই আক্ষরিক কল করতে সক্ষম হওয়া Activity
ফ্যাবিয়ান জইনডল

-4

কোটলিনে একটি এক্সটেনশন পদ্ধতি তৈরি করতে আপনাকে কোটলিন ফাইল তৈরি করতে হবে (কোনও শ্রেণি নয়) তারপরে আপনার ফাইলটি Eg হিসাবে ঘোষণা করুন:

public fun String.toLowercase(){
    // **this** is the string object
}

আপনি যে শ্রেণিতে বা ফাইলটিতে কাজ করছেন তাতে ফাংশনটি আমদানি করুন এবং এটি ব্যবহার করুন।


শিরোনাম এমনকি একটি প্রশ্নও নয়
daniel.jbatiz
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.