C#——各種參數,擴展方法

来源:https://www.cnblogs.com/GeekDragon/archive/2018/11/11/9939821.html
-Advertisement-
Play Games

餘近日複習C#之基礎知識,故作一隨筆,也是對此前幾篇博客中所記錄的傳值參數相關內容之彙總,還望諸位加以批評指正。 該博客包括以下內容: 傳值參數 引用參數 輸出參數 數組參數 具名參數 可選參數 擴展方法(this參數) 傳值參數 C#語言規範中道:“聲明時不帶修飾符的形參是值形參。一個值形參對應於 ...


餘近日複習C#之基礎知識,故作一隨筆,也是對此前幾篇博客中所記錄的傳值參數相關內容之彙總,還望諸位加以批評指正。

該博客包括以下內容:

傳值參數

引用參數

輸出參數

數組參數

具名參數

可選參數

擴展方法(this參數)

 

傳值參數

C#語言規範中道:“聲明時不帶修飾符的形參是值形參。一個值形參對應於一個局部變數,只是它的初始值來自該方法調用所提供的相應實參。

當形參是值形參時,方法調用中的對應實參必須是表達式,並且它的類型可以隱式轉換為形參的類型。

允許方法將新值賦給值參數。這樣的賦值隻影響由該值形參表示的局部存儲位置,而不會影響在方法調用時由調用方給出的實參。”

 

註意:1、值參數創建變數之副本;2、對參數之改變永遠不影響變數之值

傳值參數→值類型

        static void Main(string[] args)
        {
            int y=100;
            AddOne(y);
            System.Console.WriteLine(y);
        }

        static void AddOne(int x)//此處x便為傳值參數(或值參數)
        {
            x+=1;
            System.Console.WriteLine(x);
        }
        /*
        運行結果:
        101
        100
         */

根據結果顯示,第一行即為AddOne方法內列印出的語句,其結果為101,因為執行了x+=1;,列印出的亦為x之數值;而第二行列印出的結果是在調用方法完後y(變數)之值,我們發現,y(變數)之數值並未發生改變。

其原因便是,我們所修改的是y(變數)傳進來的一個副本,其並不影響變數之值。

 

傳值參數→引用類型,創建新的對象

static void Main(string[] args)
        {
            Student stu=new Student(){Name="Mark"};
            System.Console.WriteLine("Hashcode={0},Name={1}.",stu.GetHashCode(),stu.Name);
            SomeMethod(stu);
        }

        static void SomeMethod(Student stu)//類類型便為典型之引用類型,在此為傳值參數
        {
            stu =new Student(){Name="Mark"};
            System.Console.WriteLine("Hashcode={0},Name={1}.",stu.GetHashCode(),stu.Name);
        }

class Student
    {
        public string  Name { get; set; }
    }
 /*
    運行結果:
    Hashcode=1542680,Name=Mark.
    Hashcode=20054852,Name=Mark.
     */

根據運行結果顯示,第一行列印的便為方法之外變數的hashcode與名字,第二行列印的便為調用方法內列印的hashcode與名字。很顯然,雖然我們給它們設置的名字都是Mark,但它們的hashcode是完全不一樣的。因為第二個是我們在方法內創建的新對象(如果給其方法內的變數賦一個別的名字比如Elliot,那麼列印出的名字與hashcode都不一樣,這樣似乎更加的直觀)。

其原因在於,引用類型存儲的是實例之地址。方法外的變數stu存儲了對象之地址,傳入方法里的值也便是對象之地址,而傳值參數傳入方法內的是變數之副本(副本里也儲存的是對象之地址)。我們調用方法後,改變了副本里的值,也便就是改變了副本里之前存的地址,換成了一個新地址,那麼自然而然的指向了一個新對象。而對值參數(副本)的改變不會影響變數的值。故方法外之變數依舊指向原來的那個對象,而更改後的副本指向了一個新對象,它們互不影響。

註意:這種現象與實際工作中並無多大意義,我們用方法只是為了讀取值,不會新建個對象引用著。

 

傳值參數→引用類型,不創建對象,只操作對象

 

註意:對象還是那個對象,但對象內的值已經發生改變。

 

    class Program
    {
        static void Main(string[] args)
        {
            Student outterstu=new Student(){Name="Mark"};
            System.Console.WriteLine("Hashcode={0},Name={1}.",outterstu.GetHashCode(),outterstu.Name);
            UpdateObject(outterstu);
        }

        static void UpdateObject(Student stu)
        {
            stu.Name="Elliot";//未創建新對象,只是講對象的名字屬性的值改變了。
            System.Console.WriteLine("Hashcode={0},Name={1}.",stu.GetHashCode(),stu.Name);
        }
    }
  class Student
       {
         public string Name { get; set; }
       }
       /*
       運行結果:
        Hashcode=1542680,Name=Mark.
        Hashcode=1542680,Name=Elliot.
        */

根據運行結果顯示,未調用方法前名字為Mark,調用完之後則變成了Elliot。但是,它們的hashcode值卻都是完全一樣的,這說明它們指向的是同一個對象。而調用方法只是將對象內的值做了改動而已。(註意與引用參數情形之下加以區分,且為後話)

註意:這種現象很少見,對方法而言,其主要輸出還是靠返回值。這是該方法的副作用(side-effect)。

 

引用參數(引用形參)

C#語言規範中道:“ ref 修飾符聲明的形參是引用形參。與值形參不同,引用形參並不創建新的存儲位置。相反,引用形參表示的存儲位置恰是在方法調用中作為實參給出的那個變數所表示的存儲位置。

當形參為引用形參時,方法調用中的對應實參必須由關鍵字 ref 並後接一個與形參類型相同的 variable-reference組成。變數在可以作為引用形參傳遞之前,必須先明確賦值。

在方法內部,引用形參始終被認為是明確賦值的。”

 

註意:1、引用參數並不創建變數之副本。2、使用ref修飾符顯示指出——該方法的副作用是為了修改實際參數之值。

 

引用參數→值類型

     static void Main(string[] args)
        {
            int y=100;
            IWantSideEffect(ref y);//ref修飾符顯式指出副作用
            System.Console.WriteLine(y);
        }   

        static void IWantSideEffect(ref int x)
        {
            x+=1;
            System.Console.WriteLine(x);
        }    
        /*運行結果:
            101
            101
         */

與"傳值參數→值類型"一小程式對比可見,這一次方法外的y(變數)值發生了改變。這是因為方法的參數(x)與方法外之變數(y)所指記憶體之地址是相同的。我們在方法內改變參數所指記憶體地址中的值,則相當於變數所指記憶體地址中的值發生改變。那麼我們用變數訪問記憶體地址中存儲的值時,拿到的便是改變後的值。

 

引用參數→引用類型,創建新對象

 class Program
    {
        static void Main(string[] args)
        {
            Student outterstu=new Student(){Name="Mark"};
            System.Console.WriteLine("Hashcode={0},Name={1}.",outterstu.GetHashCode(),outterstu.Name);
            System.Console.WriteLine("----------------------------------------------");
            IWantSideEffect(ref outterstu);
            System.Console.WriteLine("Hashcode={0},Name={1}.",outterstu.GetHashCode(),outterstu.Name);
        }   

        static void IWantSideEffect(ref Student stu)
        {
            stu =new Student (){Name="Elliot"};
            System.Console.WriteLine("Hashcode={0},Name={1}.",stu.GetHashCode(),stu.Name);
        }
    }

    class Student
    {
        public string Name { get; set; }
    }
    /*
        運行結果:
        Hashcode=1542680,Name=Mark.
        ----------------------------------------------
        Hashcode=20054852,Name=Elliot.
        Hashcode=20054852,Name=Elliot.
    */

根據運行結果顯示:第一行為未調用方法時的變數之Hashcode與Name。分割線下的第一行是調用方法時列印出的Hashcode與Name,第二行是在調用方法完後再次列印變數之Hashcode與Name。我們發現,調用方法後的參數"值"與變數"值"是完全一樣的。

其原因在於,引用類型變數存儲的是對象(或曰實例)在堆記憶體上之地址。那麼當變數傳入方法時,參數中所存也便為對象在對記憶體上之地址(相同的),在方法內部之邏輯,對參數進行了修改(創建了新的對象),由於這時傳入的不是變數之”副本“,而是真真切切的變數,所以變數中所儲存之值(地址)也隨即發生了改變。因為是創建了新的對象,所以無論是參數還是變數中所存之地址是新對象之在堆記憶體上之地址,所以它們指向了同一個新對象。

 

引用參數→引用類型,不創建新的對象,只修改對象值

 

    class Program
    {
        static void Main(string[] args)
        {
            Student outterstu=new Student(){Name="Mark"};
            System.Console.WriteLine("Hashcode={0},Name={1}.",outterstu.GetHashCode(),outterstu.Name);
            System.Console.WriteLine("------------------------------------------");
            SomeSideEffect(ref outterstu);
            System.Console.WriteLine("Hashcode={0},Name={1}.",outterstu.GetHashCode(),outterstu.Name);
        }   

        static void SomeSideEffect(ref Student stu)
        {
            stu.Name="Elliot";
            System.Console.WriteLine("Hashcode={0},Name={1}.",stu.GetHashCode(),stu.Name);            
        }
    }

    class Student
    {
        public string Name { get; set; }
    }
    /*
        運行結果:
        Hashcode=1542680,Name=Mark.
        ------------------------------------------
        Hashcode=1542680,Name=Elliot.
        Hashcode=1542680,Name=Elliot.
    */

根據運行結果顯示:第一行為未調用方法時,外部變數(outterstu)的Hashcode與Name;分割線下麵的第一行是方法內部列印出來的,註意此時的Hashcode與外部變數是相同的,但是Name已經改寫了;第二行則是在調用完方法後,再次列印出外部變數之Hashcode與Name。其Hashcode值並未改變,而其Name之值已經改寫了。

與上一段程式相比,這次並沒有創建新對象,只是改變原有對象之值。

到此為止,應註意其與"傳值參數→引用類型,不創建對象,只操作對象"之大不同

 class Program
    {
        static void Main(string[] args)
        {
            Student outterstu=new Student(){Name="Mark"};
            System.Console.WriteLine("Hashcode={0},Name={1}.",outterstu.GetHashCode(),outterstu.Name);
            System.Console.WriteLine("------------------------------------------");
            SomeSideEffect(outterstu);
            System.Console.WriteLine("Hashcode={0},Name={1}.",outterstu.GetHashCode(),outterstu.Name);
        }   

        static void SomeSideEffect(Student stu)
        {
            stu.Name="Elliot";
            System.Console.WriteLine("Hashcode={0},Name={1}.",stu.GetHashCode(),stu.Name);            
        }
    }

    class Student
    {
        public string Name { get; set; }
    }
    /*
        運行結果:
        Hashcode=1542680,Name=Mark.
        ------------------------------------------
        Hashcode=1542680,Name=Elliot.
        Hashcode=1542680,Name=Elliot.
    */

上面這段代碼,我們將ref關鍵字刪除,運行後之結果並無改變,但其內涵確實極為大不相同的

當為傳值情況時,變數傳進方法時,在記憶體中創建了其自身之副本,即變數(outterstu)與參數(stu)所指向之記憶體地址是不一樣的。而在此兩個不同之記憶體地址之中,卻都保存著相同之實例在堆記憶體中之地址。

而引用參數情況則為,變數(outterstu)與參數(stu)所指記憶體地址為同一記憶體地址,在這同一記憶體地址中保存的便為實例於堆記憶體中之地址。

 

輸出參數

C#語言定義文檔道:” out 修飾符聲明的形參是輸出形參。類似於引用形參,輸出形參不創建新的存儲位置。相反,輸出形參表示的存儲位置恰是在該方法調用中作為實參給出的那個變數所表示的存儲位置

當形參為輸出形參時,方法調用中的相應實參必須由關鍵字 out 並後接一個與形參類型相同的 variable-reference組成。變數在可以作為輸出形參傳遞之前不一定需要明確賦值,但是在將變數作為輸出形參傳遞的調用之後,該變數被認為是明確賦值的。

在方法內部,與局部變數相同,輸出形參最初被認為是未賦值的,因而必須在使用它的值之前明確賦值。

在方法返回之前,該方法的每個輸出形參都必須明確賦值。“

通俗點說,比如,方法相當於加工數據之地方,而其返回值便為加工好之產品,但調用後只可產生依次。如若我們想在調用方法後得到多個值,即除了返回值之外還想拿到其他之值,則就要用到輸出參數。

 

註意:1、輸出參數並不創建變數之副本(變數與參數指向相同之記憶體地址);2、方法體內必須要有對輸出變數之賦值操作;3、使用out修飾符顯式指出——此方法之副作用為通過參數向外輸出值;4、變數初始值可有可空,終歸是要被覆蓋掉的。

在C#里,其本身就帶有Parse與TryParse兩種方法,Parse是解析,TryParse之返回值為布爾類型,判斷解析是否成功,若解析成功後我們想拿到解析後之值,而其返回值被布爾值所占用,此時便用到輸出參數之功能。如圖:

輸出參數→值類型

那麼,我們自己給double加一個"偽"TryParse方法。

  class Program
    {
        static void Main(string[] args)
        {
            string arg="123";
            string arg2="asd";
            double x=0;
            double y=0;
            bool b1=DoubleParser.TryParse(arg,out x);
            bool b2=DoubleParser.TryParse(arg2,out y); 

            if (b1==false)
            {
                System.Console.WriteLine("Input Error!");
            }
            else
                System.Console.WriteLine(x);

                System.Console.WriteLine("---------------------");

            if (b2==false)
            {
                System.Console.WriteLine("Input Error!");
                System.Console.WriteLine(y);
            }
        }           
    }

    class DoubleParser
    {
        public static bool TryParse(string input,out double result)
        {
            try
            {
                result =double.Parse (input);
                return true;
            }
            catch
            {
                result=0;//必須給result賦初值,在方法返回之前,該方法的每個輸出形參都必須明確賦值。
                return false;
            }
        }
    }
    /*
        運行結果:
                    123
                    ---------------------
                    Input Error!
                    0
    */

第一行是解析成功之x之值,分割線下麵為解析失敗之y值,其原有值亦被覆蓋成0。

 

輸出參數→引用類型

變數有無初始值都可,即便其有初始值,即引用著一個在堆記憶體中之對象。調用方法後,對參數進行賦值操作,因為變數與參數指向的是同一記憶體地址,則對參數值修改後(創建新對象),變數也引用上了新創建之對象。

舉例:

有一個"學生工廠",不斷的輸送人才出來,其內部有兩個邏輯,一是判斷成績是否符合要求,一是判斷學生是否有姓名。如果兩條其中有一項不滿足,則為false,人才就流失了;如果均滿足的話,就創造出了人才(即創建一個新對象)。

    class Program
    {
        static void Main(string[] args)
        {
            Student stu=null;
            bool b=StudentFactory.Creat("Elliot",90,out stu);

            if (b==true)
            {
                System.Console.WriteLine("Name is {0},Score is {1}.",stu.Name,stu.Score);
            }
        }           
        
    }

    class Student
    {
        public string Name { get; set; }
        public int Score { get; set; }
    }

    class StudentFactory
    {
        public static bool Creat(string stuName,int stuScore,out Student result)
        {
            result =null;
            
            if (string.IsNullOrEmpty(stuName))//判斷姓名是否為空
            {
                return false;
            }
            
            if (stuScore<60)//判斷成績
            {
                return false;
            }

            result=new Student (){Name=stuName,Score=stuScore};//創建一個新對象
            return true;
        }
    }

    /*
       運行結果:
       Name is Elliot,Score is 90.
     */

 

在此,稍作總結,對於ref修飾符來說是專為“改變”;對於out修飾符來說是專為"輸出"

 

數組參數

數組參數聲明時會用params關鍵字修飾,且必須是形參列表中最後一個,且只有一個

直接看例子,我們要計算一個數組內所有元素之和。

static void Main(string[] args)
        {
            int[] arrray={1,2,3,4,5};
            int result=Sum(arrray);
            System.Console.WriteLine(result);
            //運行結果:15
        }           

        static int Sum(int[] intArray)
        {
            int sum=0;
            foreach (var i in intArray)
            {
                sum+=i;
            }
            return sum;

我們在調用這個方法之前,必須有一個已經聲明好的數組才可以放進去,但是,若在方法之參數列表內加一params修飾,就不必這麼麻煩了。

        static void Main(string[] args)
        {
            int result=Sum(1,2,3,4,5);//直接輸入數據即可,無需創建數組
            System.Console.WriteLine(result);
            //運行結果:15
        }           

        static int Sum(params int[] intArray)//加params修飾
        {
            int sum=0;
            foreach (var i in intArray)
            {
                sum+=i;
            }
            return sum;
        }        

還有其自有之Split方法。

  static void Main(string[] args)
        {
            //還有其自帶之Split方法
            string str ="Elliot;Mark,Ben.";
            string []strC=str.Split(';',',','.');//刪除人名間之符號
            foreach (var name in strC)
            {
                System.Console.WriteLine(name);
            }
            /*運行結果:
            Elliot
            Mark
            Ben
             */
        }         

 

具名參數

參數之位置不再受約束,而且提高可讀性。

 static void Main(string[] args)
        {
          printf(Age:19,Name:"Elliot");//沒有按照參數列表之順序存入數據
          //運行結果:My name isElliot,I'm 19 years old.
        }           

        static void printf(string Name,int Age)
        {
            System.Console.WriteLine("My name is{0},I'm {1} years old.",Name,Age);
        }

 

可選參數

參數具有預設值。

static void Main(string[] args)
        {
            printf();//不輸入數據,則列印出預設值
            //運行結果:My name isElliot,I'm 19 years old.

        }         
        
        static void printf(string Name="Elliot",int Age=19)//聲明時賦有預設值
        {
            System.Console.WriteLine("My name is{0},I'm {1} years old.",Name,Age);
        }  

 

擴展方法(this參數)

註意:1、方法必須是公有、靜態的,即被public static所修飾;2、必須是形參列表中之第一個,且被this關鍵字所修飾;3、必須由一個靜態類(一般名為SomeTypeExtension)來統一收納對SomeType之擴展方法。

比如,我們想對一個double類型之變數值進行四捨五入,然而其自身並無此方法,必須藉助Math中的Round方法。

        static void Main(string[] args)
        {
            double x=3.14159;
            double y=Math.Round(x,4);//只能藉助於Math類之Round方法
            System.Console.WriteLine(y);
            //運行結果:3.1416
        }           

所以,我們對double類型之變數加一個擴展方法:

class Program
    {
        static void Main(string[] args)
        {
            double x=3.14159;
            double y=x.Round(4);//這裡x就是input,其已自動傳入了
            System.Console.WriteLine(y);
            //運行結果:3.1416
        }           
    }

    public static class DoubleExtension
    {
        public static double Round(this double input,int digital)//參數列表分別對應輸入值(this修飾),保留小數點後幾位
        {
            double result=Math.Round(input,digital);
            return result;
        } 

這樣,就方便甚多。

其擴展方法還與LINQ有很大之聯繫,只因餘現時所學尚淺,不敢妄議。待日後餘學識見漲再加以補充。

 

總結:

傳值參數:參數預設傳遞方式

引用參數:用於需要修改實際參數之值

輸出參數:用於除需返回值外還需其他輸出

數組參數:簡化方法調用

具名參數:提高可讀性,且參數之位置不受約束

可選參數:參數具有預設值

擴展方法(this參數):為目標數據類型“追加”方法

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Actuator可能大家非常熟悉,它是springboot提供對應用自身監控,以及對應用系統配置查看等功能。spring-boot-starter-actuator模塊的實現對於實施微服務的中小團隊來說,可以有效地減少監控系統在採集應用指標時的開發量。當然,它也並不是萬能的,有時候我們也需要對其做一... ...
  • 在百萬級和千萬級數據級別進行插入,pymongo的insert_many()方法有著很強的優勢。本文做了對原生pymongo和Django框架中經常使用的mongoengine進行測試,以進行對比。 ...
  • Python的簡介 Python是一種面向對象的、動態的腳本語言,可用來設計網頁和開發後臺功能。其創始人Guido van Rossum於1989年聖誕節期間創造了這門語言。 (圖片來自百度) Python的種類 CPython Jython IronPython PyPy …… 與Java相比 P ...
  • print(“hello,world”) pycharm設置 1. 選擇python 解析器,目的是確定pycharm 的運行環境。 方法: File-->Settings-->Project:unititled-->Project Interpreter 2、配置PyCharm的背景。 File- ...
  • 當文件夾里文件很多時,往往需要很長時間我們才能找到想要的文件 利用os模塊,我們就可以利用關鍵字在文件夾里進行模糊搜索。 在folder1文件夾下尋找符合以下條件的文件 1.除了‘.gif’類型之外的文件 2.名字中含有‘fish’或‘muggy’ ...
  • 數組 一維數組 定義:類型符 數組名 [常量表達式] int a[]={1,2,3,4,5,}; 1 #include<stdio.h> 2 #define NUM 6 3 void main() 4 { 5 int a[NUM]; 6 printf("輸入NUM個整數:\n"); 7 for(in ...
  • 基礎很重要,基礎很重要,基礎很重要。重要的事情說三遍,。 今天聊一聊Java的數據比較,這個範圍比較大,基礎類型的比較、引用類型的比較。 前提: 1、Java和c#都提供自動裝箱和自動拆箱操作,何為自動裝箱,簡單點說就是將值類型轉換成為引用類型,自動拆箱就是將引用類型轉換成為值類型。並且我們還經常被 ...
  • 1.字元編碼過濾器 實現功能,在a.jsp中填寫用戶名提交到b.jsp,在b.jsp中讀取參數名。 a.jsp b.jsp 若需要讀取參數的頁面太多,需要在每一個頁面都添加<% request.setCharacterEncoding("UTF-8");%>,該方法行不通。字元編碼過濾器通過配置參數 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...