text:
/* pngwtran.c - transforms the data in a row for PNG writers
 *
 * Copyright (c) 2018 Cosmin Truta
 * Copyright (c) 1998-2002,2004,2006-2016,2018 Glenn Randers-Pehrson
 * Copyright (c) 1996-1997 Andreas Dilger
 * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
 *
 * This code is released under the libpng license.
 * For conditions of distribution and use, see the disclaimer
 * and license in png.h
 */

#include "pngpriv.h"

#ifdef PNG_WRITE_SUPPORTED
#ifdef PNG_WRITE_TRANSFORMS_SUPPORTED

#ifdef PNG_WRITE_PACK_SUPPORTED
/* Pack pixels into bytes.  Pass the true bit depth in bit_depth.  The
 * row_info bit depth should be 8 (one pixel per byte).  The channels
 * should be 1 (this only happens on grayscale and paletted images).
 */
static void
png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth)
{
   png_debug(1, "in png_do_pack");

   if (row_info->bit_depth == 8 &&
      row_info->channels == 1)
   {
      switch ((int)bit_depth)
      {
         case 1:
         {
            png_bytep sp, dp;
            int mask, v;
            png_uint_32 i;
            png_uint_32 row_width = row_info->width;

            sp = row;
            dp = row;
            mask = 0x80;
            v = 0;

            for (i = 0; i < row_width; i++)
            {
               if (*sp != 0)
                  v |= mask;

               sp++;

               if (mask > 1)
                  mask >>= 1;

               else
               {
                  mask = 0x80;
                  *dp = (png_byte)v;
                  dp++;
                  v = 0;
               }
            }

            if (mask != 0x80)
               *dp = (png_byte)v;

            break;
         }

         case 2:
         {
            png_bytep sp, dp;
            unsigned int shift;
            int v;
            png_uint_32 i;
            png_uint_32 row_width = row_info->width;

            sp = row;
            dp = row;
            shift = 6;
            v = 0;

            for (i = 0; i < row_width; i++)
            {
               png_byte value;

               value = (png_byte)(*sp & 0x03);
               v |= (value << shift);

               if (shift == 0)
               {
                  shift = 6;
                  *dp = (png_byte)v;
                  dp++;
                  v = 0;
               }

               else
                  shift -= 2;

               sp++;
            }

            if (shift != 6)
               *dp = (png_byte)v;

            break;
         }

         case 4:
         {
            png_bytep sp, dp;
            unsigned int shift;
            int v;
            png_uint_32 i;
            png_uint_32 row_width = row_info->width;

            sp = row;
            dp = row;
            shift = 4;
            v = 0;

            for (i = 0; i < row_width; i++)
            {
               png_byte value;

               value = (png_byte)(*sp & 0x0f);
               v |= (value << shift);

               if (shift == 0)
               {
                  shift = 4;
                  *dp = (png_byte)v;
                  dp++;
                  v = 0;
               }

               else
                  shift -= 4;

               sp++;
            }

            if (shift != 4)
               *dp = (png_byte)v;

            break;
         }

         default:
            break;
      }

      row_info->bit_depth = (png_byte)bit_depth;
      row_info->pixel_depth = (png_byte)(bit_depth * row_info->channels);
      row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
          row_info->width);
   }
}
#endif

#ifdef PNG_WRITE_SHIFT_SUPPORTED
/* Shift pixel values to take advantage of whole range.  Pass the
 * true number of bits in bit_depth.  The row should be packed
 * according to row_info->bit_depth.  Thus, if you had a row of
 * bit depth 4, but the pixels only had values from 0 to 7, you
 * would pass 3 as bit_depth, and this routine would translate the
 * data to 0 to 15.
 */
static void
png_do_shift(png_row_infop row_info, png_bytep row,
    png_const_color_8p bit_depth)
{
   png_debug(1, "in png_do_shift");

   if (row_info->color_type != PNG_COLOR_TYPE_PALETTE)
   {
      int shift_start[4], shift_dec[4];
      unsigned int channels = 0;

      if ((row_info->color_type & PNG_COLOR_MASK_COLOR) != 0)
      {
         shift_start[channels] = row_info->bit_depth - bit_depth->red;
         shift_dec[channels] = bit_depth->red;
         channels++;

         shift_start[channels] = row_info->bit_depth - bit_depth->green;
         shift_dec[channels] = bit_depth->green;
         channels++;

         shift_start[channels] = row_info->bit_depth - bit_depth->blue;
         shift_dec[channels] = bit_depth->blue;
         channels++;
      }

      else
      {
         shift_start[channels] = row_info->bit_depth - bit_depth->gray;
         shift_dec[channels] = bit_depth->gray;
         channels++;
      }

      if ((row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0)
      {
         shift_start[channels] = row_info->bit_depth - bit_depth->alpha;
         shift_dec[channels] = bit_depth->alpha;
         channels++;
      }

      /* With low row depths, could only be grayscale, so one channel */
      if (row_info->bit_depth < 8)
      {
         png_bytep bp = row;
         size_t i;
         unsigned int mask;
         size_t row_bytes = row_info->rowbytes;

         if (bit_depth->gray == 1 && row_info->bit_depth == 2)
            mask = 0x55;

         else if (row_info->bit_depth == 4 && bit_depth->gray == 3)
            mask = 0x11;

         else
            mask = 0xff;

         for (i = 0; i < row_bytes; i++, bp++)
         {
            int j;
            unsigned int v, out;

            v = *bp;
            out = 0;

            for (j = shift_start[0]; j > -shift_dec[0]; j -= shift_dec[0])
            {
               if (j > 0)
                  out |= v << j;

               else
                  out |= (v >> (-j)) & mask;
            }

            *bp = (png_byte)(out & 0xff);
         }
      }

      else if (row_info->bit_depth == 8)
      {
         png_bytep bp = row;
         png_uint_32 i;
         png_uint_32 istop = channels * row_info->width;

         for (i = 0; i < istop; i++, bp++)
         {
            unsigned int c = i%channels;
            int j;
            unsigned int v, out;

            v = *bp;
            out = 0;

            for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c])
            {
               if (j > 0)
                  out |= v << j;

               else
                  out |= v >> (-j);
            }

            *bp = (png_byte)(out & 0xff);
         }
      }

      else
      {
         png_bytep bp;
         png_uint_32 i;
         png_uint_32 istop = channels * row_info->width;

         for (bp = row, i = 0; i < istop; i++)
         {
            unsigned int c = i%channels;
            int j;
            unsigned int value, v;

            v = png_get_uint_16(bp);
            value = 0;

            for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c])
            {
               if (j > 0)
                  value |= v << j;

               else
                  value |= v >> (-j);
            }
            *bp++ = (png_byte)((value >> 8) & 0xff);
            *bp++ = (png_byte)(value & 0xff);
         }
      }
   }
}
#endif

#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED
static void
png_do_write_swap_alpha(png_row_infop row_info, png_bytep row)
{
   png_debug(1, "in png_do_write_swap_alpha");

   {
      if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
      {
         if (row_info->bit_depth == 8)
         {
            /* This converts from ARGB to RGBA */
            png_bytep sp, dp;
            png_uint_32 i;
            png_uint_32 row_width = row_info->width;

            for (i = 0, sp = dp = row; i < row_width; i++)
            {
               png_byte save = *(sp++);
               *(dp++) = *(sp++);
               *(dp++) = *(sp++);
               *(dp++) = *(sp++);
               *(dp++) = save;
            }
         }

#ifdef PNG_WRITE_16BIT_SUPPORTED
         else
         {
            /* This converts from AARRGGBB to RRGGBBAA */
            png_bytep sp, dp;
            png_uint_32 i;
            png_uint_32 row_width = row_info->width;

            for (i = 0, sp = dp = row; i < row_width; i++)
            {
               png_byte save[2];
               save[0] = *(sp++);
               save[1] = *(sp++);
               *(dp++) = *(sp++);
               *(dp++) = *(sp++);
               *(dp++) = *(sp++);
               *(dp++) = *(sp++);
               *(dp++) = *(sp++);
               *(dp++) = *(sp++);
               *(dp++) = save[0];
               *(dp++) = save[1];
            }
         }
#endif /* WRITE_16BIT */
      }

      else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
      {
         if (row_info->bit_depth == 8)
         {
            /* This converts from AG to GA */
            png_bytep sp, dp;
            png_uint_32 i;
            png_uint_32 row_width = row_info->width;

            for (i = 0, sp = dp = row; i < row_width; i++)
            {
               png_byte save = *(sp++);
               *(dp++) = *(sp++);
               *(dp++) = save;
            }
         }

#ifdef PNG_WRITE_16BIT_SUPPORTED
         else
         {
            /* This converts from AAGG to GGAA */
            png_bytep sp, dp;
            png_uint_32 i;
            png_uint_32 row_width = row_info->width;

            for (i = 0, sp = dp = row; i < row_width; i++)
            {
               png_byte save[2];
               save[0] = *(sp++);
               save[1] = *(sp++);
               *(dp++) = *(sp++);
               *(dp++) = *(sp++);
               *(dp++) = save[0];
               *(dp++) = save[1];
            }
         }
#endif /* WRITE_16BIT */
      }
   }
}
#endif

#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED
static void
png_do_write_invert_alpha(png_row_infop row_info, png_bytep row)
{
   png_debug(1, "in png_do_write_invert_alpha");

   {
      if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
      {
         if (row_info->bit_depth == 8)
         {
            /* This inverts the alpha channel in RGBA */
            png_bytep sp, dp;
            png_uint_32 i;
            png_uint_32 row_width = row_info->width;

            for (i = 0, sp = dp = row; i < row_width; i++)
            {
               /* Does nothing
               *(dp++) = *(sp++);
               *(dp++) = *(sp++);
               *(dp++) = *(sp++);
               */
               sp+=3; dp = sp;
               *dp = (png_byte)(255 - *(sp++));
            }
         }

#ifdef PNG_WRITE_16BIT_SUPPORTED
         else
         {
            /* This inverts the alpha channel in RRGGBBAA */
            png_bytep sp, dp;
            png_uint_32 i;
            png_uint_32 row_width = row_info->width;

            for (i = 0, sp = dp = row; i < row_width; i++)
            {
               /* Does nothing
               *(dp++) = *(sp++);
               *(dp++) = *(sp++);
               *(dp++) = *(sp++);
               *(dp++) = *(sp++);
               *(dp++) = *(sp++);
               *(dp++) = *(sp++);
               */
               sp+=6; dp = sp;
               *(dp++) = (png_byte)(255 - *(sp++));
               *dp     = (png_byte)(255 - *(sp++));
            }
         }
#endif /* WRITE_16BIT */
      }

      else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
      {
         if (row_info->bit_depth == 8)
         {
            /* This inverts the alpha channel in GA */
            png_bytep sp, dp;
            png_uint_32 i;
            png_uint_32 row_width = row_info->width;

            for (i = 0, sp = dp = row; i < row_width; i++)
            {
               *(dp++) = *(sp++);
               *(dp++) = (png_byte)(255 - *(sp++));
            }
         }

#ifdef PNG_WRITE_16BIT_SUPPORTED
         else
         {
            /* This inverts the alpha channel in GGAA */
            png_bytep sp, dp;
            png_uint_32 i;
            png_uint_32 row_width = row_info->width;

            for (i = 0, sp = dp = row; i < row_width; i++)
            {
               /* Does nothing
               *(dp++) = *(sp++);
               *(dp++) = *(sp++);
               */
               sp+=2; dp = sp;
               *(dp++) = (png_byte)(255 - *(sp++));
               *dp     = (png_byte)(255 - *(sp++));
            }
         }
#endif /* WRITE_16BIT */
      }
   }
}
#endif

/* Transform the data according to the user's wishes.  The order of
 * transformations is significant.
 */
void /* PRIVATE */
png_do_write_transformations(png_structrp png_ptr, png_row_infop row_info)
{
   png_debug(1, "in png_do_write_transformations");

   if (png_ptr == NULL)
      return;

#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED
   if ((png_ptr->transformations & PNG_USER_TRANSFORM) != 0)
      if (png_ptr->write_user_transform_fn != NULL)
         (*(png_ptr->write_user_transform_fn)) /* User write transform
                                                 function */
             (png_ptr,  /* png_ptr */
             row_info,  /* row_info: */
                /*  png_uint_32 width;       width of row */
                /*  size_t rowbytes;         number of bytes in row */
                /*  png_byte color_type;     color type of pixels */
                /*  png_byte bit_depth;      bit depth of samples */
                /*  png_byte channels;       number of channels (1-4) */
                /*  png_byte pixel_depth;    bits per pixel (depth*channels) */
             png_ptr->row_buf + 1);      /* start of pixel data for row */
#endif

#ifdef PNG_WRITE_FILLER_SUPPORTED
   if ((png_ptr->transformations & PNG_FILLER) != 0)
      png_do_strip_channel(row_info, png_ptr->row_buf + 1,
          !(png_ptr->flags & PNG_FLAG_FILLER_AFTER));
#endif

#ifdef PNG_WRITE_PACKSWAP_SUPPORTED
   if ((png_ptr->transformations & PNG_PACKSWAP) != 0)
      png_do_packswap(row_info, png_ptr->row_buf + 1);
#endif

#ifdef PNG_WRITE_PACK_SUPPORTED
   if ((png_ptr->transformations & PNG_PACK) != 0)
      png_do_pack(row_info, png_ptr->row_buf + 1,
          (png_uint_32)png_ptr->bit_depth);
#endif

#ifdef PNG_WRITE_SWAP_SUPPORTED
#  ifdef PNG_16BIT_SUPPORTED
   if ((png_ptr->transformations & PNG_SWAP_BYTES) != 0)
      png_do_swap(row_info, png_ptr->row_buf + 1);
#  endif
#endif

#ifdef PNG_WRITE_SHIFT_SUPPORTED
   if ((png_ptr->transformations & PNG_SHIFT) != 0)
      png_do_shift(row_info, png_ptr->row_buf + 1,
           &(png_ptr->shift));
#endif

#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED
   if ((png_ptr->transformations & PNG_SWAP_ALPHA) != 0)
      png_do_write_swap_alpha(row_info, png_ptr->row_buf + 1);
#endif

#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED
   if ((png_ptr->transformations & PNG_INVERT_ALPHA) != 0)
      png_do_write_invert_alpha(row_info, png_ptr->row_buf + 1);
#endif

#ifdef PNG_WRITE_BGR_SUPPORTED
   if ((png_ptr->transformations & PNG_BGR) != 0)
      png_do_bgr(row_info, png_ptr->row_buf + 1);
#endif

#ifdef PNG_WRITE_INVERT_SUPPORTED
   if ((png_ptr->transformations & PNG_INVERT_MONO) != 0)
      png_do_invert(row_info, png_ptr->row_buf + 1);
#endif
}
#endif /* WRITE_TRANSFORMS */
#endif /* WRITE */

repo_language: C

mime_type: text/x-c


text:
{
    // Folders to use for output
    // Caution: it overrides the value from the command line
    // It's not advised this option in the book.json
    "output": null,

    // Generator to use for building
    // Caution: it overrides the value from the command line
    // It's not advised this option in the book.json
    //"generator": "site",

    // Book title and description (defaults are extracted from the README)
    "title": "The Swift Programming Language 正體中文版",
    "description": "",

    // For ebook format, the extension to use for generation (default is detected from output extension)
    // "epub", "pdf", "mobi"
    // Caution: it overrides the value from the command line
    // It's not advised this option in the book.json
    //"extension": null,

    // GitHub information (defaults are extracted using git)
    "github": "https://github.com/CocoaHeads-Kaohsiung/The_Swift_Programming_Language_zh-TW.git",
    "githubHost": "https://github.com/",

    // Plugins list, can contain "-name" for removing default plugins
    "plugins": ["autocover","richquotes","toggle-chapters","toc","md-include"],

    // Global configuration for plugins
    "pluginsConfig": {
        "fontSettings": {
            "theme": "sepia", "night" or "white",
            "family": "serif" or "sans",
            "size": 1 to 4
        },
        "autocover": {
            "title": "The Swift Programming Language 正體中文版",
            "author": "Aaron, Dofi, Evan, FrankWu, Mikimoto, Marcus",
            "font": {
                        "size": null,
                        "family": "Impact",
                        "color": '#FFF'
            },
            "size": {
                        "w": 1800,
                        "h": 2360
            },
            "background": {
                        "color": '#09F'
            }
        },
        "richquotes": {
            "todos" : true /*false by default*/
        }
    },

    // Set another theme with your own layout
    // It's recommended to use plugins or add more options for default theme, though
    // See https://github.com/GitbookIO/gitbook/issues/209
    "theme": "./localtheme",

    // Links in template (null: default, false: remove, string: new value)
    "links": {
        // Link to home in the top-left corner
        "home": null,

        // Links in top of sidebar
        "about": null,
        "issues": null,
        "contribute": null,

        // Sharing links
        "sharing": {
            "google": null,
            "facebook": null,
            "twitter": null
        }
    },

    // Options for PDF generation
    "pdf": {
        // Add toc at the end of the file
        "toc": true,

        // Add page numbers to the bottom of every page
        "pageNumbers": true,

        // Font size for the fiel content
        "fontSize": 12,

        // Paper size for the pdf
        // Choices are [u’a0’, u’a1’, u’a2’, u’a3’, u’a4’, u’a5’, u’a6’, u’b0’, u’b1’, u’b2’, u’b3’, u’b4’, u’b5’, u’b6’, u’legal’, u’letter’]
        "paperSize": "a4",

        // Margin (in pts)
        // Note: 72 pts equals 1 inch
        "margin": {
            "right": 62,
            "left": 62,
            "top": 36,
            "bottom": 36
        }
    }
}

mime_type: text/plain


text:
# Summary

* [序](README.md)
* [歡迎使用 Swift](book/Welcome.md)
   * [關於 Swift (Mikimoto)](book/101_About_Swift.md)
   * [Swift 簡易教學 (Evan)](book/102_A_Swift_Tour.md)
* [語言手冊](book/README)
   * [基本語法 (Dofi)](book/201_The_Basics.md)
   * [基本運算元 (Mikimoto)](book/202_Basic_Operators.md)
   * [字串與字元 (Evan)](book/203_Strings_and_Characters.md)
   * [聚集型態 (YoGa)](book/204_Collection_Types.md)
   * [Control Flow (DDT)](book/205_Control_Flow.md)
   * [Functions (Hank Hsiao)](book/206_Functions.md)
   * [閉包 (MRSHIH)](book/207_Closures.md)
   * [Enumerations](book/208_Enumerations.md)
   * [Classes and Structures](book/209_Classes_and_Structures.md)
   * [Properties](book/210_Properties.md)
   * [Methods](book/211_Methods.md)
   * [Subscripts](book/212_Subscripts.md)
   * [Inheritance](book/213_Inheritance.md)
   * [Initialization](book/README)
   * [Deinitialization](book/README)
   * [Automatic Reference Counting](book/README)
   * [Optional Chaining](book/README)
   * [Type Casting](book/README)
   * [Nested Types](book/README)
   * [Extensions](book/README)
   * [Protocols](book/README)
   * [Generics](book/README)
   * [Advanced Operators](book/README)
* [語言參考](book/README)
   * [About the Language Reference](book/README)
   * [Lexical Structure](book/README)
   * [Types](book/README)
   * [Expressions](book/README)
   * [Statements](book/README)
   * [Declarations](book/README)
   * [Attributes](book/README)
   * [Patterns](book/README)
   * [Generic Parameters and Arguments](book/README)
   * [Summary of the Grammar](book/README)


text:
The Swift Programming Language 正體中文版
====================================

本份文件由 [The Swift Programming Language](http://developer.apple.com/library/prerelease/ios/documentation/swift/conceptual/swift_programming_language/) 翻譯而來，我們非常歡迎任何人一起加入此翻譯計畫，來協助更多正體中文地區的新手開發者學習 Swift.

## 注意事項 ##
---
請大家在 SUMMARY.md 章節後面用括號加上該章節認領人的名字，以免重工

## 致謝 ##
---
感謝下面人員參與本翻譯計畫：(依照暱稱第一個英文字母排序)
- Aaron
- Dofi
- DDT
- Evan
- FrankWu
- Hank Hsiao
- Mikimoto
- Marcus
- MRSHIH
- HankH
- YoGa
- Yulin0629

## 我想協助翻譯 ##
---
我們非常需要大家一起加入協助翻譯工作，加入協助翻譯的方式下列兩種方式都可以：

- Fork 本專案，修正後以 Pull Request 方式提出修正，請自行在 README.md 感謝人員中加入自己的名字
- 加入 CocoaHeads Kaohsiung 翻譯計畫，請在 Issue 中提出「我想加入本計畫」我們就會把該帳號加入翻譯小組名單，您就可以直接參與修改

## 我有問題想反映或討論 ##
---
歡迎人和疑問或需求，可以在 Issue 中提出與討論


text:
# 基本語法

Swift 是專為 iOS 和 OS X 應用程式開發工作所設計的一套全新的程式語言。然而，Swift 的許多部分，對於具備 C 和 Objective-C 開發經驗的你來說，是相當熟悉的。

Swift 針對 C 和 Objective-C 的所有基本型別，都提供了它自己的專屬版本，包括，整數的Int、浮點數值（floating-point value）的 Double 和 Float、布林值（Boolean）的 Bool，以及文字資料專用的 String。Swift 也提供了兩個主要集合（collection）型別的增強版本：Array 和 Dictionary，而相關描述請參考《集合型別》一節的內容。

就和 C 一樣，Swift 會使用變數來保存內容值，並以一個識別名稱來加以參照。Swift 還廣泛使用了內容值無法被更動的變數－也就是所謂的「常數」（constants），而且性能遠比 C 裡頭的常數還要強大許多。在 Switf 裡頭到處都會看到常數的蹤跡，因而使得程式碼變得更加安全，並且還能讓你在需要用到那些無須變更其內容值的意圖更加明確。

除了熟悉的型別以外，Swift 還採用了在 Objective-C 裡頭所沒有的進階型別。這裡頭包括了能讓你去建立，並傳遞整個內容值群組的「多元組」（tuples）。「多元組」可以讓多個值以一個單一複合值的形式從函數傳回。

Swift 還引入了「選擇性」（optional）型別，以便用來處理欠缺內容值的情況。「選擇性」代表目前是處於「這裡有個值，而且它等於 x」，或是「這裡完全沒有任何值」的其中一種情況。「選擇性」很類似在 Objective-C 裡頭搭配指標來使用 nil 的情況，但是它們可以被運用在任何型別上，而不只是只能用在類別上。「選擇性」會比 Objective-C 裡的 nil 指標更安全，也更具表達性，而且是屬於許多 Switf 的強大功能的重要關鍵。

「選擇性」可用來當作「Swift 是一種型別安全語言(type safe language)」的實證之一。Swift 會透過這個機制來協助你明確地表達，內容值是屬於你的程式碼可以進行處理的型別。假如你的程式碼期望處理的是一個 String 的話，型別安全性（type safety）會防止你錯誤地傳給它一個 Int。這項機制讓你可以在開發過程當中，盡可能提早捕捉到錯誤，以便加以修正。

## 常數與變數
常數與變數都會把一個特定型別的值（像是數值 10 或字串"Hello"）與一個名稱（例如，maximumNumberOfLoginAttempts  或 welcomeMessage）關連在一起。「常數」的值一旦被設定好就不能再被更動，而「變數」在未來的任何時候，都可以設定成一個不同的值。

### 常數與變數的宣告方式
常數與變數在它們被拿來使用之前，都必須先進行宣告（declare）。你會搭配關鍵字 let 來宣告常數，並使用關鍵字 var 來宣告變數。底下是一個用來示範常數和變數，可以被用來追蹤使用者試圖登入次數的範例：

	let maximumNumberOfLoginAttempts = 10
	var currentLoginAttempt = 0

這段程式碼可以被解讀成：

「宣告一個名為 maximumNumberOfLoginAttempts 的新常數，並賦予它一個 10 的內容值。然後，宣告一個名為 currentLoginAttempt 的新變數，並賦予它一個 0 的初始值。」

在這個範例當中，允許嘗試登入的最大次數被宣告成一個常數，因為最大值永遠都不會更動。目前試圖登入計數器是被宣告為一個變數，因為這個值必須在每次嘗試登入失敗後，就被遞增一次。

你可以在單一行裡頭，以逗號字元（,）分隔的方式，來同時宣告多個常數或變數：

	var x = 0.0, y = 0.0, z = 0.0

> 備註

> 假如在你的程式碼裡頭某個已保存的值，永遠不會再發生更動的話，通常可以使用關鍵字 let 來把它宣告為一個常數。只對需要能夠被進行更動其內容的值使用變數。

### 型別標註
你可以在宣告某個常數或變數時，提供一個「型別標註」（type annotation）來清楚的指出該常數或變數可以保存的內容值的型別。在常數或變數名稱後面放置一個冒號字元（:），再加上一個空白字元之後，接著再加上要使用的型別名稱，就可以編寫出一個型別標註資訊。

底下範例會對一個名為 welcomeMessage 的變數提供一個型別標註，以表示那個變數可以儲存型別 String 的值：

	var welcomeMessage: String

在宣告裡的冒號意思是「... 屬於型別 ...」，因此上述程式碼可以被解讀成：

「宣告一個屬於型別 String，且名為 welcomeMessage 的變數。」

片語「屬於型別  String」意思是「可以儲存任何 String 的值」。可以把它想成是能夠被保存的「內容型別」（或「內容類型」）的意思。

welcomeMessage 變數現在可以被設定成任何的字串值，而不會有錯誤發生：

	welcomeMessage = "Hello"

> 備註

> 實際上，你真的得去撰寫型別標註的情況並不多見。假如你在定義某個常數或變數時，去為它提供一個初始值的話，就如同《型別安全性與型別推斷》一節所描述的那樣，Swift 幾乎都能夠推斷出那個常數或變數所要使用的型別。在上述的 welcomeMessage 範例當中，由於沒有提供初始值，因此就得搭配一個型別標註來指定 welcomeMessage 的型別，而不是採取以初始值來進行推斷的方式。

### 常數與變數的命名方式
你幾乎可以使用任何你所喜歡的字元，甚至是 Unicode（通用碼）字元，來對你的常數和變數名稱進行命名：

	let π = 3.14159
	let 你好 = "你好世界"
	let 🐶🐮 = "dogcow"

常數和變數名稱，無法包含數學符號、箭頭、專用（private-use）或無效的 Unicode 碼位（code point），或者是畫線或畫框字元等等。此外，開頭的第一個字元不能使用數字字元，但是數字字元可以使用在名稱的其他位置上。

一旦你已經宣告某個特定型別的常數或變數，你就無法再以相同名稱去做重複宣告的動作，或者是改變它去儲存不同型別的內容值。此外，你不能夠把某個常數變更成變數，或者是把一個變數變更成常數。

> 備註

> 假如你需要以保留給 Swift 的關鍵字來當作某個常數或變數的名稱的話，你可以在使用它來當做名稱的時候，透過以反單引號字元（`）來圍住關鍵字的方式，即可達成這個目的。然而，你應該避免使用關鍵字來當作常數或變數的名稱，除非你真的已經別無選擇。

你可以把現有變數的值，更改成相容型別的另一個值。在底下範例當中，friendlyWelcome 的值會從 "Hello!" 變成了 "Bonjour!"：

	var friendlyWelcome = "Hello!"
	friendlyWelcome = "Bonjour!"
	// friendlyWelcome 現在是 "Bonjour!" 了

與變數所不同的是，常數的值只要被設定好，就不能再次被更動了。若試圖這樣做的話，你就會在進行程式碼的編譯作業時，得到一個錯誤訊息：

	let languageName = "Swift"
	languageName = "Swift++"
	// 這是一個編譯時期錯誤 - languageName 無法被進行更動

### 常數與變數的傾印方式
你可以搭配 println 函數來把常數或變數的目前內容值給傾印出來：

	println(friendlyWelcome)
	// 印出 "Bonjour!"

println 是一個全域函數，而它能夠把內容值以及隨後的一個斷行字元，給傾印成一個適當輸出結果，舉例來說，假如你正在使用 Xcode 的話，println 會把它的輸出給傾印到 Xcode 的主控台（console）面板當中（另一個函數 print 則會執行相同的處理作業，只是不會在內容值被印出的最後面，又另外附加一個斷行字元）。

println 函數會把你傳給它的任何 String 的內容值都給傾印出來：

    println("This is a string")
    // 印出 "This is a string"

println 函數可以運用類似 Cocoa 的 NSLog 函數的方式，來傾印出更複雜的日誌訊息（logging messages）。而這些訊息都可以引入常數和變數的目前內容值。

Swift 會使用「字串內插機制」（string interpolation），來把某個常數或變數的名稱當成一個保留位置給引入到某個較長的字串當中，以便提示 Swift 把它給替換成常數或變數的目前內容值。若要進行這項作業，你可以用一組小括弧來刮住名稱，並且在左括弧的前面，加入一個反斜線字元（\）來對它進行脫逸處理（escape）：

    println("The current value of friendlyWelcome is \(friendlyWelcome)")
    // 印出 "The current value of friendlyWelcome is Bonjour!"

> 備註

> 關於你可以用來搭配字串內插機制的所有選項，請參考《字串內插機制》一節內容。

## 註解
使用「註解」（comments）來把要當作筆記，或者用來提醒自己的不可執行文字，給引入到你的程式碼當中。註解會在你進行程式碼的編譯作業時，被 Swift 編譯器給忽略掉。

在 Swift 裡的註解內容，與 C 裡頭的註解文字非常類似。以兩個斜線字元（//）為首，即可標示出單行註解（single-line comments）：

	// 這是一行註解文字

你也可以透過以一個斜線字元緊接著一個星號字元（/*）的組合為開始，並以一個星號字元緊接著一個斜線字元（*/）的組合為結束的方式，來撰寫多行註解（multiline comments）：

	/* 這也是一段註解文字，
	但可以撰寫成好幾行內容 */

和 C 的多行註解所不同的是，Swift 裡的多行註解可以被套疊在其他的多行註解裡頭。你可以透過先展開一個多行註解區塊，然後在第一個區塊範圍裡頭，再展開第二個多行註解的方式，來撰寫出巢狀註解（nested comments）。在結束（關閉）第二個區塊範圍後，再結束第一個註解區塊：

	/* 這是第一個多行註解區塊的開始部分
	/* 這是第二個，也是被套疊在其中的多行註解 */
	這是第一個多行註解區塊的結尾部分 */

巢狀多行註解讓你即便是程式碼裡頭已經含有多行註解的情況下，仍然可以快速且輕易地將龐大的程式碼區塊範圍給註解起來。

## 分號字元（;）
和許多語言所不同的是，Swift 並不要求你一定得在程式碼裡的每個陳述式（statement）的後面，都加上一個分號字元（;），但你還是可以根據自己的習慣來加入這個分號字元。不過，假如你是想要把多個獨立陳述式給編寫在同一行裡頭的話，那就一定要在每個獨立陳述式的後面都加入分號字元：

	let cat = "🐱"; println(cat)
	// 印出 "🐱"

## 整數（Integers）
「整數」是像 42 和 -23 這類不帶有小數部分的純數字。整數可以是有號整數（正數、零，或負數），或者無號整數（正數或零）。

Swift 提供了 8 、16、32，和 64 位元形式的有號（signed）和無號（unsigned）整數。這些整數都遵循著與 C 類似的命名慣例－比如說，一個 8 位元無號整數就是屬於 UInt8 型別，而一個 32 位元有號整數，則是屬於 Int32 的型別。就和 Swift 裡的所有型別一樣，這些整數型別都有個以大寫字母為首的名稱。

### 整數範圍
你可以搭配 min 和 max 屬性來取得每個整數型別的最小值和最大值：

	let minValue = UInt8.min // minValue 等於 0，而且是屬於 UInt8 型別
	let maxValue = UInt8.max // maxValue 等於 255，而且是屬於 UInt8 型別

這些屬性的值都是屬於適當大小的數字型別（如同上述的 UInt8），而且都可被運用在帶有相同型別的其他數值的陳述式裡頭。

### Int
在大多數情況下，你並不需要在自己的程式碼裡頭，指出整數的特定大小。Swift 提供了一種額外的整數型別－Int 。而這個型別會與目前平台的原生詞組（word），擁有相同的尺寸大小：

* 在 32 位元平台上，Int 是與 Int32 擁有相同大小。

* 在 64 位元平台上，Int 是與 Int64 擁有相同大小。

除非你必須使用到特定的整數大小，否則通常只要對程式碼裡頭的整數使用 Int 即可。這有助於程式碼的一致性和互用性。以 32 位元平台來說，Int 可以保存在 -2,147,483,648 與 2,147,483,647 之間的任何數值，而這對許多整數範圍來說，已經相當夠用了。

### UInt
Swift也提供無號的整數型別，`UInt`，和目前平台原生詞組(word)有相同的大小

* 在 32 位元平台上，UInt 是與 UInt32 擁有相同大小。
* 在 64 位元平台上，UInt 是與 UInt64 擁有相同大小。

> 注意：
>
只有在你需要儲存和目前平台原生字組(word)相同大小的無號整數時才使用UInt。否則建議使用Int，即使要儲存的值已知是非負數。統一使用Int有助程式的互用性，避免不同數字型別間需要轉換，且符合整數型別推斷，請參考型別安全和型別推斷

## 浮點數

浮點數是含有小數部份的數字，像是`3.141591`，`0.1`和`-273.15`。

浮點數可以表示的範圍遠比整數大很多，可以儲存遠大於或遠小於`Int`所能表示的數字。Swift提供兩種有號浮點數的型別

* `Double`表示64位元浮點數

* `Float`表示32位元浮點數

> 注意：
>
`Double`有至少小數點下15位的精確度，而`Float`有至少小數點下6位的精確度。選擇適當的浮點數型別取決於你的程式碼需要處理的數值範圍。當情況允許兩種型別時，建議使用`Double`。


text:
# Subscripts
---
Classes, structures, and enumerations can define *subscripts*, which are shortcuts for accessing the member elements of a collection, list, or sequence. You use subscripts to set and retrieve values by index without needing separate methods for setting and retrieval. For example, you access elements in an `Array` instance as `someArray[index]` and elements in a `Dictionary` instance as `someDictionary[key]`.

You can define multiple subscripts for a single type, and the appropriate subscript overload to use is selected based on the type of index value you pass to the subscript. Subscripts are not limited to a single dimension, and you can define subscripts with multiple input parameters to suit your custom type’s needs.

## Subscript Syntax

Subscripts enable you to query instances of a type by writing one or more values in square brackets after the instance name. Their syntax is similar to both instance method syntax and computed property syntax. You write subscript definitions with the `subscript` keyword, and specify one or more input parameters and a return type, in the same way as instance methods. Unlike instance methods, subscripts can be read-write or read-only. This behavior is communicated by a getter and setter in the same way as for computed properties:

```swift
subscript(index: Int) -> Int {
    get {
        // return an appropriate subscript value here
    }
    set(newValue) {
        // perform a suitable setting action here
    }
}
```

The type of `newValue` is the same as the return value of the subscript. As with computed properties, you can choose not to specify the setter’s `(newValue)` parameter. A default parameter called `newValue` is provided to your setter if you do not provide one yourself.

As with read-only computed properties, you can drop the `get` keyword for read-only subscripts:

```swift
subscript(index: Int) -> Int {
    // return an appropriate subscript value here
}
```

Here’s an example of a read-only subscript implementation, which defines a `TimesTable` structure to represent an n-times-table of integers:

```swift
struct TimesTable {
    let multiplier: Int
    subscript(index: Int) -> Int {
        return multiplier * index
    }
}
let threeTimesTable = TimesTable(multiplier: 3)
println("six times three is \(threeTimesTable[6])")
// prints "six times three is 18"
```

In this example, a new instance of `TimesTable` is created to represent the three-times-table. This is indicated by passing a value of `3` to the structure’s `initializer` as the value to use for the instance’s `multiplier` parameter.

You can query the `threeTimesTable` instance by calling its subscript, as shown in the call to `threeTimesTable[6]`. This requests the sixth entry in the three-times-table, which returns a value of `18`, or `3` times `6`.

> NOTE
>
> An n-times-table is based on a fixed mathematical rule. It is not appropriate to set `threeTimesTable[someIndex]` to a new value, and so the subscript for `TimesTable` is defined as a read-only subscript.

## Subscript Usage

The exact meaning of “subscript” depends on the context in which it is used. Subscripts are typically used as a shortcut for accessing the member elements in a collection, list, or sequence. You are free to implement subscripts in the most appropriate way for your particular class or structure’s functionality.

For example, Swift’s `Dictionary` type implements a subscript to set and retrieve the values stored in a `Dictionary` instance. You can set a value in a dictionary by providing a key of the dictionary’s key type within subscript braces, and assigning a value of the dictionary’s value type to the subscript:

```swift
var numberOfLegs = ["spider": 8, "ant": 6, "cat": 4]
numberOfLegs["bird"] = 2
```

The example above defines a variable called `numberOfLegs` and initializes it with a dictionary literal containing three key-value pairs. The type of the `numberOfLegs` dictionary is inferred to be `Dictionary<String, Int>`. After creating the dictionary, this example uses subscript assignment to add a `String` key of `"bird"` and an `Int` value of `2` to the dictionary.

For more information about `Dictionary` subscripting, see [Accessing and Modifying a Dictionary](204_Collection_Types.html#accessing-and-modifying-a-dictionary "Accessing and Modifying a Dictionary").

> NOTE
>
> Swift’s `Dictionary` type implements its key-value subscripting as a subscript that takes and receives an *optional* type. For the `numberOfLegs` dictionary above, the key-value subscript takes and returns a value of type `Int?`, or “optional int”. The `Dictionary` type uses an optional subscript type to model the fact that not every key will have a value, and to give a way to delete a value for a key by assigning a `nil` value for that key.

## Subscript Options

Subscripts can take any number of input parameters, and these input parameters can be of any type. Subscripts can also return any type. Subscripts can use variable parameters and variadic parameters, but cannot use in-out parameters or provide default parameter values.

A class or structure can provide as many subscript implementations as it needs, and the appropriate subscript to be used will be inferred based on the types of the value or values that are contained within the subscript braces at the point that the subscript is used. This definition of multiple subscripts is known as *subscript overloading*.

While it is most common for a subscript to take a single parameter, you can also define a subscript with multiple parameters if it is appropriate for your type. The following example defines a `Matrix` structure, which represents a two-dimensional matrix of `Double` values. The `Matrix` structure’s subscript takes two integer parameters:

```swift
struct Matrix {
    let rows: Int, columns: Int
    var grid: Double[]
    init(rows: Int, columns: Int) {
        self.rows = rows
        self.columns = columns
        grid = Array(count: rows * columns, repeatedValue: 0.0)
    }
    func indexIsValidForRow(row: Int, column: Int) -> Bool {
        return row >= 0 && row < rows && column >= 0 && column < columns
    }
    subscript(row: Int, column: Int) -> Double {
        get {
            assert(indexIsValidForRow(row, column: column), "Index out of range")
            return grid[(row * columns) + column]
        }
        set {
            assert(indexIsValidForRow(row, column: column), "Index out of range")
            grid[(row * columns) + column] = newValue
        }
    }
}
```

`Matrix` provides an initializer that takes two parameters called `rows` and `columns`, and creates an array that is large enough to store `rows * columns` values of type `Double`. Each position in the matrix is given an initial value of `0.0`. To achieve this, the array’s size, and an initial cell value of `0.0`, are passed to an array initializer that creates and initializes a new array of the correct size. This initializer is described in more detail in [Creating and Initializing an Array](204_Collection_Types.html#creating-and-initializing-an-array "Creating and Initializing an Array").

You can construct a new `Matrix` instance by passing an appropriate row and column count to its initializer:

```swift
var matrix = Matrix(rows: 2, columns: 2)
```

The preceding example creates a new `Matrix` instance with two rows and two columns. The `grid` array for this `Matrix` instance is effectively a flattened version of the matrix, as read from top left to bottom right:

![Art/subscriptMatrix01_2x.png](https://developer.apple.com/library/prerelease/ios/documentation/swift/conceptual/swift_programming_language/Art/subscriptMatrix01_2x.png "Art/subscriptMatrix01_2x.png")

Values in the matrix can be set by passing row and column values into the subscript, separated by a comma:

```swift
matrix[0, 1] = 1.5
matrix[1, 0] = 3.2
```

These two statements call the subscript’s setter to set a value of `1.5` in the top right position of the matrix (where `row` is `0` and `column` is `1`), and `3.2` in the bottom left position (where `row` is `1` and `column` is `0`):

![Art/subscriptMatrix02_2x.png](https://developer.apple.com/library/prerelease/ios/documentation/swift/conceptual/swift_programming_language/Art/subscriptMatrix02_2x.png "Art/subscriptMatrix02_2x.png")

The `Matrix` subscript’s getter and setter both contain an assertion to check that the subscript’s `row` and `column` values are valid. To assist with these assertions, `Matrix` includes a convenience method called `indexIsValid`, which checks whether the requested `row` or `column` is outside the bounds of the matrix:

```swift
func indexIsValidForRow(row: Int, column: Int) -> Bool {
    return row >= 0 && row < rows && column >= 0 && column < columns
}
```

An assertion is triggered if you try to access a subscript that is outside of the matrix bounds:

```swift
let someValue = matrix[2, 2]
// this triggers an assert, because [2, 2] is outside of the matrix bounds
```


text:
# 關於 Swift

    重要注意事項：
        本份文件為初步描述 Swift 相關技術的開發用文件。蘋果公司提供此份文件來協助您在蘋果官方產品上應用此技術。本份文件將在最後釋出的作業系統上進行驗證與測試，而 Swift 語言將依據此份規格進行實作，過程中如有任何變更與修正將會更新此份文件。
        本文件後續更新版本中將可能包含一些尚在測試中的規格或 API。

Swift 是一種用於開發 iOS 和 OS X 應用程式的新程式語言。它結合了 C 和 Objective-C 的優點，並且改善了 C 相容性限制的缺點。它採用了許多安全的程式設計模式（Programming Patterns），並添加了很多新特性，這些將使程式設計更簡單、靈活，也更有趣。Swift 基於成熟及倍受喜愛的 Cocoa 和 Cocoa Touch 程式框架（Frameworks）。學習 Swift 將可以讓您重新回味軟體開發是如何運作。

Swift 的開發已經進行許多年了。蘋果公司在已經發展成熟的編譯器（compiler）、除錯器（debugger）及系統資訊框架（framework infrastructure）基礎上開發 Swift。我們用物件記憶體自動回收管理技術（ARC，Automatic Reference Counting）來簡化記憶體管理。我們有基於 Foundation 和 Cocoa 的基礎上先進而且已經成為標準的系統結構堆疊（framework stack）。本身支援 區塊（block）、集合迭代（collection literal）與模組化（module）的 Objective-C，讓新的語言不需額外的努力就可以跟現代程式語言的技術接軌。感謝過去的所有努力，我們現在才能介紹用於未來 Apple 軟體開發的新語言。

Objective-C 開發者應該會對 Swift 這個新程式語言非常熟悉。Swift 與 Objective-C 在參數命名上有同樣的可閱讀性，在動態物件模組（dynamic object module）也有相同的能力。可以讓您無縫接軌到現有的 Cocoa 程式框架（frameworks），並且可以相容於 Objective-C 的程式碼。在此基礎上 Swift 引進了許多新功能，在程序導向（procedural）及物件導向（object oriented）兩種型態的語言間巧妙的做了結合。

Swift 對於初學者也很友善，它是第一個兼具工業等級的系統程式設計語言，以及充滿趣味及直觀的腳本語言（script language）兩種特性的程式語言。它支援 playground 模式。這個模式可以讓程式設計師不用編譯與執行應用程式，就能立即看到 Swift 程式碼的執行結果。

Swift 結合了現代程式語言中最睿智的思維和蘋果電腦深厚的工程師文化。編譯器對效能的最佳化與 Swift 對開發過程的最佳化兩者可以毫無違和且互不干擾。Swift 既可以用於開發 “hello, world” 這樣的小程式，也可以用於開發一套完整的作業系統。前述所有的功能讓 Swift 對於開發者和蘋果電腦來說都是一項非常划算的投資。

用 Swift 設計 iOS 和 OS X 的應用將是一場美妙的體驗，Swift 將會繼續不斷的開發新功能與相容性，我們對 Swift 未來充滿信心並且等不及想知道您用 Swift 開發了什麼新玩意。


text:
# Enumerations
---
An *enumeration* defines a common type for a group of related values and enables you to work with those values in a type-safe way within your code.

If you are familiar with C, you will know that C enumerations assign related names to a set of integer values. Enumerations in Swift are much more flexible, and do not have to provide a value for each member of the enumeration. If a value (known as a “raw” value) *is* provided for each enumeration member, the value can be a string, a character, or a value of any integer or floating-point type.

Alternatively, enumeration members can specify associated values of *any* type to be stored along with each different member value, much as unions or variants do in other languages. You can define a common set of related members as part of one enumeration, each of which has a different set of values of appropriate types associated with it.

Enumerations in Swift are first-class types in their own right. They adopt many features traditionally supported only by classes, such as computed properties to provide additional information about the enumeration’s current value, and instance methods to provide functionality related to the values the enumeration represents. Enumerations can also define initializers to provide an initial member value; can be extended to expand their functionality beyond their original implementation; and can conform to protocols to provide standard functionality.

For more on these capabilities, see [Properties]( 210_Properties.html "Properties"), [Methods](211_Methods.html "Methods"), [Initialization](214_Initialization.html "Initialization"), [Extensions](220_Extensions.html "Extensions"), and [Protocols](221_Protocols.html "Protocols").

## Enumeration Syntax

You introduce enumerations with the `enum` keyword and place their entire definition within a pair of braces:

```swift
enum SomeEnumeration {
    // enumeration definition goes here
}
```

Here’s an example for the four main points of a compass:

```swift
enum CompassPoint {
    case North
    case South
    case East
    case West
}
```

The values defined in an enumeration (such as `North`, `South`, `East`, and `West`) are the *member values* (or *members*) of that enumeration. The `case` keyword indicates that a new line of member values is about to be defined.

> **NOTE**
>
> Unlike C and Objective-C, Swift enumeration members are not assigned a default integer value when they are created. In the `CompassPoints` example above, `North`, `South`, `East` and `West` do not implicitly equal `0`, `1`, `2` and `3`. Instead, the different enumeration members are fully-fledged values in their own right, with an explicitly-defined type of `CompassPoint`.

Multiple member values can appear on a single line, separated by commas:

```swift
enum Planet {
    case Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune
}
```

Each enumeration definition defines a brand new type. Like other types in Swift, their names (such as `CompassPoint` and `Planet`) should start with a capital letter. Give enumeration types singular rather than plural names, so that they read as self-evident:

```swift
var directionToHead = CompassPoint.West
```

The type of `directionToHead` is inferred when it is initialized with one of the possible values of `CompassPoint`. Once `directionToHead` is declared as a `CompassPoint`, you can set it to a different `CompassPoint` value using a shorter dot syntax:

```swift
directionToHead = .East
```

The type of `directionToHead` is already known, and so you can drop the type when setting its value. This makes for highly readable code when working with explicitly-typed enumeration values.

## Matching Enumeration Values with a Switch Statement

You can match individual enumeration values with a `switch` statement:

```swift
directionToHead = .South
switch directionToHead {
case .North:
println("Lots of planets have a north")
case .South:
println("Watch out for penguins")
case .East:
    println("Where the sun rises")
case .West:
    println("Where the skies are blue")
}
// prints "Watch out for penguins"
```

You can read this code as:

“Consider the value of `directionToHead`. In the case where it equals `.North`, print `"Lots of planets have a north"`. In the case where it equals `.South`, print `"Watch out for penguins"`.”

…and so on.

As described in [Control Flow](205_Control_Flow.html "Control Flow"), a `switch` statement must be exhaustive when considering an enumeration’s members. If the `case` for `.West` is omitted, this code does not compile, because it does not consider the complete list of `CompassPoint` members. Requiring exhaustiveness ensures that enumeration members are not accidentally omitted.

When it is not appropriate to provide a `case` for every enumeration member, you can provide a default case to cover any members that are not addressed explicitly:

```swift
let somePlanet = Planet.Earth
switch somePlanet {
case .Earth:
    println("Mostly harmless")
default:
    println("Not a safe place for humans")
}
// prints "Mostly harmless"
```

## Associated Values

The examples in the previous section show how the members of an enumeration are a defined (and typed) value in their own right. You can set a constant or variable to `Planet.Earth`, and check for this value later. However, it is sometimes useful to be able to store *associated values* of other types alongside these member values. This enables you to store additional custom information along with the member value, and permits this information to vary each time you use that member in your code.

You can define Swift enumerations to store associated values of any given type, and the value types can be different for each member of the enumeration if needed. Enumerations similar to these are known as *discriminated unions*, *tagged unions*, or *variants* in other programming languages.

For example, suppose an inventory tracking system needs to track products by two different types of barcode. Some products are labeled with 1D barcodes in UPC-A format, which uses the numbers 0 to 9. Each barcode has a “number system” digit, followed by ten “identifier” digits. These are followed by a “check” digit to verify that the code has been scanned correctly:

![Art/barcode_UPC_2x.png](https://developer.apple.com/library/prerelease/ios/documentation/swift/conceptual/swift_programming_language/Art/barcode_UPC_2x.png "Art/barcode_UPC_2x.png")

Other products are labeled with 2D barcodes in QR code format, which can use any ISO 8859-1 character and can encode a string up to 2,953 characters long:

![Art/barcode_QR_2x.png](https://developer.apple.com/library/prerelease/ios/documentation/swift/conceptual/swift_programming_language/Art/barcode_QR_2x.png "Art/barcode_QR_2x.png")

It would be convenient for an inventory tracking system to be able to store UPC-A barcodes as a tuple of three integers, and QR code barcodes as a string of any length.

In Swift, an enumeration to define product barcodes of either type might look like this:

```swift
enum Barcode {
    case UPCA(Int, Int, Int)
    case QRCode(String)
}
```

This can be read as:

“Define an enumeration type called `Barcode`, which can take either a value of `UPCA` with an associated value of type (`Int`, `Int`, `Int`), or a value of `QRCode` with an associated value of type `String`.”

This definition does not provide any actual `Int` or `String` values—it just defines the *type* of associated values that `Barcode` constants and variables can store when they are equal to `Barcode.UPCA` or `Barcode.QRCode`.

New barcodes can then be created using either type:

```swift
var productBarcode = Barcode.UPCA(8, 85909_51226, 3)
```

This example creates a new variable called `productBarcode` and assigns it a value of `Barcode.UPCA` with an associated tuple value of `(8, 8590951226, 3)`. The provided “identifier” value has an underscore within its integer literal—`85909_51226`—to make it easier to read as a barcode.

The same product can be assigned a different type of barcode:

```swift
productBarcode = .QRCode("ABCDEFGHIJKLMNOP")
```

At this point, the original `Barcode.UPCA` and its integer values are replaced by the new `Barcode.QRCode` and its string value. Constants and variables of type `Barcode` can store either a `.UPCA` or a `.QRCode` (together with their associated values), but they can only store one of them at any given time.

The different barcode types can be checked using a switch statement, as before. This time, however, the associated values can be extracted as part of the switch statement. You extract each associated value as a constant (with the `let` prefix) or a variable (with the `var` prefix) for use within the `switch` case’s body:

```swift
switch productBarcode {
case .UPCA(let numberSystem, let identifier, let check):
    println("UPC-A with value of \(numberSystem), \(identifier), \(check).")
case .QRCode(let productCode):
    println("QR code with value of \(productCode).")
}
// prints "QR code with value of ABCDEFGHIJKLMNOP."
```

If all of the associated values for a enumeration member are extracted as constants, or if all are extracted as variables, you can place a single `var` or `let` annotation before the member name, for brevity:

```swift
switch productBarcode {
case let .UPCA(numberSystem, identifier, check):
    println("UPC-A with value of \(numberSystem), \(identifier), \(check).")
case let .QRCode(productCode):
    println("QR code with value of \(productCode).")
}
// prints "QR code with value of ABCDEFGHIJKLMNOP."
```

## Raw Values

The barcode example in [Associated Values](#associated-values "Associated Values") shows how members of an enumeration can declare that they store associated values of different types. As an alternative to associated values, enumeration members can come prepopulated with default values (called *raw values*), which are all of the same type.

Here’s an example that stores raw ASCII values alongside named enumeration members:

```swift
enum ASCIIControlCharacter: Character {
    case Tab = "\t"
    case LineFeed = "\n"
    case CarriageReturn = "\r"
}
```

Here, the raw values for an enumeration called `ASCIIControlCharacter` are defined to be of type `Character`, and are set to some of the more common ASCII control characters. `Character` values are described in [Strings and Characters](203_Strings_and_Characters.html "Strings and Characters").

Note that raw values are *not* the same as associated values. Raw values are set to prepopulated values when you first define the enumeration in your code, like the three ASCII codes above. The raw value for a particular enumeration member is always the same. Associated values are set when you create a new constant or variable based on one of the enumeration’s members, and can be different each time you do so.

Raw values can be strings, characters, or any of the integer or floating-point number types. Each raw value must be unique within its enumeration declaration. When integers are used for raw values, they auto-increment if no value is specified for some of the enumeration members.

The enumeration below is a refinement of the earlier `Planet` enumeration, with raw integer values to represent each planet’s order from the sun:

```swift
enum Planet: Int {
    case Mercury = 1, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune
}
```

Auto-incrementation means that `Planet.Venus` has a raw value of `2`, and so on.

Access the raw value of an enumeration member with its `toRaw` method:

```swift
let earthsOrder = Planet.Earth.toRaw()
// earthsOrder is 3
```

Use an enumeration’s `fromRaw` method to try to find an enumeration member with a particular raw value. This example identifies Uranus from its raw value of `7`:

```swift
let possiblePlanet = Planet.fromRaw(7)
// possiblePlanet is of type Planet? and equals Planet.Uranus
```

Not all possible `Int` values will find a matching planet, however. Because of this, the `fromRaw` method returns an *optional* enumeration member. In the example above, `possiblePlanet` is of type `Planet?`, or “optional `Planet`.”

If you try to find a Planet with a position of `9`, the optional `Planet` value returned by `fromRaw` will be `nil`:

```swift
let positionToFind = 9
if let somePlanet = Planet.fromRaw(positionToFind) {
    switch somePlanet {
    case .Earth:
        println("Mostly harmless")
    default:
        println("Not a safe place for humans")
    }
} else {
    println("There isn't a planet at position \(positionToFind)")
}
// prints "There isn't a planet at position 9"
```

This example uses optional binding to try to access a planet with a raw value of `9`. The statement `if let somePlanet = Planet.fromRaw(9)` retrieves an optional `Planet`, and sets `somePlanet` to the contents of that optional `Planet` if it can be retrieved. In this case, it is not possible to retrieve a planet with a position of `9`, and so the `else` branch is executed instead.


text: # 歡迎使用 Swift


text:
# Classes and Structures
---
*Classes* and *structures* are general-purpose, flexible constructs that become the building blocks of your program’s code. You define properties and methods to add functionality to your classes and structures by using exactly the same syntax as for constants, variables, and functions.

Unlike other programming languages, Swift does not require you to create separate interface and implementation files for custom classes and structures. In Swift, you define a class or a structure in a single file, and the external interface to that class or structure is automatically made available for other code to use.

> **NOTE**
>
> An instance of a *class* is traditionally known as an *object*. However, Swift classes and structures are much closer in functionality than in other languages, and much of this chapter describes functionality that can apply to instances of *either* a class or a structure type. Because of this, the more general term *instance* is used.

## Comparing Classes and Structures

Classes and structures in Swift have many things in common. Both can:

- Define properties to store values
- Define methods to provide functionality
- Define subscripts to provide access to their values using subscript syntax
- Define initializers to set up their initial state
- Be extended to expand their functionality beyond a default implementation
- Conform to protocols to provide standard functionality of a certain kind

For more information, see [Properties](210_Properties.html "Properties"), [Methods](211_Methods.html "Methods"), [Subscripts](212_Subscripts.html "Subscripts"), [Initialization](214_Initialization.html "Initialization"), [Extensions](220_Extensions.html "Extensions"), and [Protocols](221_Protocols.html "Protocols").

Classes have additional capabilities that structures do not:

- Inheritance enables one class to inherit the characteristics of another.
- Type casting enables you to check and interpret the type of a class instance at runtime.
- Deinitializers enable an instance of a class to free up any resources it has assigned.
- Reference counting allows more than one reference to a class instance.

For more information, see [Inheritance](213_Inheritance.html "Inheritance"), [Type Casting](218_Type_Casting.html "Type Casting"), [Initialization](214_Initialization.html "Initialization"), and [Automatic Reference Counting](216_Automatic_Reference_Counting.html "Automatic Reference Counting").

> **NOTE**
>
> Structures are always copied when they are passed around in your code, and do not use reference counting.

### Definition Syntax

Classes and structures have a similar definition syntax. You introduce classes with the `class` keyword and structures with the `struct` keyword. Both place their entire definition within a pair of braces:

```swift
class SomeClass {
    // class definition goes here
}
struct SomeStructure {
    // structure definition goes here
}
```

> **NOTE**
>
> Whenever you define a new class or structure, you effectively define a brand new Swift type. Give types `UpperCamelCase` names (such as `SomeClass` and `SomeStructure` here) to match the capitalization of standard Swift types (such as `String`, `Int`, and `Bool`). Conversely, always give properties and methods `lowerCamelCase` names (such as `frameRate` and `incrementCount`) to differentiate them from type names.

Here’s an example of a structure definition and a class definition:

```swift
struct Resolution {
    var width = 0
    var height = 0
}
class VideoMode {
    var resolution = Resolution()
    var interlaced = false
    var frameRate = 0.0
    var name: String?
}
```

The example above defines a new structure called `Resolution`, to describe a pixel-based display resolution. This structure has two stored properties called `width` and `height`. Stored properties are constants or variables that are bundled up and stored as part of the class or structure. These two properties are inferred to be of type `Int` by setting them to an initial integer value of `0`.

The example above also defines a new class called `VideoMode`, to describe a specific video mode for video display. This class has four variable stored properties. The first, `resolution`, is initialized with a new `Resolution` structure instance, which infers a property type of `Resolution`. For the other three properties, new `VideoMode` instances will be initialized with an `interlaced` setting of `false` (meaning “non-interlaced video”), a playback frame rate of `0.0`, and an optional `String` value called `name`. The name property is automatically given a default value of `nil`, or “no `name` value”, because it is of an optional type.

### Class and Structure Instances

The `Resolution` structure definition and the `VideoMode` class definition only describe what a `Resolution` or `VideoMode` will look like. They themselves do not describe a specific resolution or video mode. To do that, you need to create an instance of the structure or class.

The syntax for creating instances is very similar for both structures and classes:

```swift
let someResolution = Resolution()
let someVideoMode = VideoMode()
```

Structures and classes both use initializer syntax for new instances. The simplest form of initializer syntax uses the type name of the class or structure followed by empty parentheses, such as `Resolution()` or `VideoMode()`. This creates a new instance of the class or structure, with any properties initialized to their default values. Class and structure initialization is described in more detail in [Initialization](214_Initialization.html "Initialization").

### Accessing Properties

You can access the properties of an instance using *dot syntax*. In dot syntax, you write the property name immediately after the instance name, separated by a period (`.`), without any spaces:

```swift
println("The width of someResolution is \(someResolution.width)")
// prints "The width of someResolution is 0"
```

In this example, `someResolution.width` refers to the `width` property of `someResolution`, and returns its default initial value of `0`.

You can drill down into sub-properties, such as the `width` property in the `resolution` property of a `VideoMode`:

```swift
println("The width of someVideoMode is \(someVideoMode.resolution.width)")
// prints "The width of someVideoMode is 0"
```

You can also use dot syntax to assign a new value to a variable property:

```swift
someVideoMode.resolution.width = 1280
println("The width of someVideoMode is now \(someVideoMode.resolution.width)")
// prints "The width of someVideoMode is now 1280"
```

> **NOTE**
>
> Unlike Objective-C, Swift enables you to set sub-properties of a structure property directly. In the last example above, the `width` property of the `resolution` property of `someVideoMode` is set directly, without your needing to set the entire `resolution` property to a new value.

### Memberwise Initializers for Structure Types

All structures have an automatically-generated *memberwise initializer*, which you can use to initialize the member properties of new structure instances. Initial values for the properties of the new instance can be passed to the memberwise initializer by name:

```swift
let vga = Resolution(width: 640, height: 480)
```

Unlike structures, class instances do not receive a default memberwise initializer. Initializers are described in more detail in [Initialization](214_Initialization.html "Initialization").

## Structures and Enumerations Are Value Types

A *value type* is a type that is *copied* when it is assigned to a variable or constant, or when it is passed to a function.

You’ve actually been using value types extensively throughout the previous chapters. In fact, all of the basic types in Swift—integers, floating-point numbers, Booleans, strings, arrays and dictionaries—are value types, and are implemented as structures behind the scenes.

All structures and enumerations are value types in Swift. This means that any structure and enumeration instances you create—and any value types they have as properties—are always copied when they are passed around in your code.

Consider this example, which uses the `Resolution` structure from the previous example:

```swift
let hd = Resolution(width: 1920, height: 1080)
var cinema = hd
```

This example declares a constant called `hd` and sets it to a `Resolution` instance initialized with the width and height of full HD video (`1920` pixels wide by `1080` pixels high).

It then declares a variable called `cinema` and sets it to the current value of `hd`. Because `Resolution` is a structure, a *copy* of the existing instance is made, and this new copy is assigned to `cinema`. Even though `hd` and `cinema` now have the same width and height, they are two completely different instances behind the scenes.

Next, the `width` property of `cinema` is amended to be the width of the slightly-wider 2K standard used for digital cinema projection (`2048` pixels wide and `1080` pixels high):

```swift
cinema.width = 2048
```

Checking the `width` property of `cinema` shows that it has indeed changed to be `2048`:

```swift
println("cinema is now \(cinema.width) pixels wide")
// prints "cinema is now 2048 pixels wide"
```

However, the `width` property of the original `hd` instance still has the old value of `1920`:

```swift
println("hd is still \(hd.width) pixels wide")
// prints "hd is still 1920 pixels wide"
```

When `cinema` was given the current value of `hd`, the *values* stored in `hd` were copied into the new `cinema` instance. The end result is two completely separate instances, which just happened to contain the same numeric values. Because they are separate instances, setting the width of `cinema` to `2048` doesn’t affect the width stored in `hd`.

The same behavior applies to enumerations:

```swift
enum CompassPoint {
    case North, South, East, West
}
var currentDirection = CompassPoint.West
let rememberedDirection = currentDirection
currentDirection = .East
if rememberedDirection == .West {
    println("The remembered direction is still .West")
}
// prints "The remembered direction is still .West"
```

When `rememberedDirection` is assigned the value of `currentDirection`, it is actually set to a copy of that value. Changing the value of `currentDirection` thereafter does not affect the copy of the original value that was stored in `rememberedDirection`.

## Classes Are Reference Types

Unlike value types, *reference types* are *not* copied when they are assigned to a variable or constant, or when they are passed to a function. Rather than a copy, a reference to the same existing instance is used instead.

Here’s an example, using the `VideoMode` class defined above:

```swift
let tenEighty = VideoMode()
tenEighty.resolution = hd
tenEighty.interlaced = true
tenEighty.name = "1080i"
tenEighty.frameRate = 25.0
```

This example declares a new constant called `tenEighty` and sets it to refer to a new instance of the `VideoMode` class. The video mode is assigned a copy of the HD resolution of `1920` by `1080` from before. It is set to be interlaced, and is given a name of `"1080i"`. Finally, it is set to a frame rate of `25.0` frames per second.

Next, `tenEighty` is assigned to a new constant, called `alsoTenEighty`, and the frame rate of `alsoTenEighty` is modified:

```swift
let alsoTenEighty = tenEighty
alsoTenEighty.frameRate = 30.0
```

Because classes are reference types, `tenEighty` and `alsoTenEighty` actually both refer to the *same* `VideoMode` instance. Effectively, they are just two different names for the same single instance.

Checking the `frameRate` property of `tenEighty` shows that it correctly reports the new frame rate of `30.0` from the underlying `VideoMode` instance:

```swift
println("The frameRate property of tenEighty is now \(tenEighty.frameRate)")
// prints "The frameRate property of tenEighty is now 30.0"
```

Note that `tenEighty` and `alsoTenEighty` are declared as *constants*, rather than variables. However, you can still change `tenEighty.frameRate` and `alsoTenEighty.frameRate` because the values of the `tenEighty` and `alsoTenEighty` constants themselves do not actually change. `tenEighty` and `alsoTenEighty` themselves do not “store” the `VideoMode` instance—instead, they both *refer* to a `VideoMode` instance behind the scenes. It is the `frameRate` property of the underlying `VideoMode` that is changed, not the values of the constant references to that `VideoMode`.

### Identity Operators

Because classes are reference types, it is possible for multiple constants and variables to refer to the same single instance of a class behind the scenes. (The same is not true for structures and enumerations, because they are value types and are always copied when they are assigned to a constant or variable, or passed to a function.)

It can sometimes be useful to find out if two constants or variables refer to exactly the same instance of a class. To enable this, Swift provides two identity operators:

- Identical to (`===`)
- Not identical to (`!==`)

Use these operators to check whether two constants or variables refer to the same single instance:

```swift
if tenEighty === alsoTenEighty {
    println("tenEighty and alsoTenEighty refer to the same Resolution instance.")
}
// prints "tenEighty and alsoTenEighty refer to the same Resolution instance."
```

Note that “identical to” (represented by three equals signs, or `===`) does not mean the same thing as “equal to” (represented by two equals signs, or `==`):

- “Identical to” means that two constants or variables of class type refer to exactly the same class instance.
- “Equal to” means that two instances are considered “equal” or “equivalent” in value, for some appropriate meaning of “equal”, as defined by the type’s designer.

When you define your own custom classes and structures, it is your responsibility to decide what qualifies as two instances being “equal”. The process of defining your own implementations of the “equal to” and “not equal to” operators is described in [Equivalence Operators](223_Advanced_Operators.html#equivalence-operators "Equivalence Operators").

### Pointers

If you have experience with C, C++, or Objective-C, you may know that these languages use *pointers* to refer to addresses in memory. A Swift constant or variable that refers to an instance of some reference type is similar to a pointer in C, but is not a direct pointer to an address in memory, and does not require you to write an asterisk (``*) to indicate that you are creating a reference. Instead, these references are defined like any other constant or variable in Swift.

## Choosing Between Classes and Structures

You can use both classes and structures to define custom data types to use as the building blocks of your program’s code.

However, structure instances are always passed by *value*, and class instances are always passed by *reference*. This means that they are suited to different kinds of tasks. As you consider the data constructs and functionality that you need for a project, decide whether each data construct should be defined as a class or as a structure.

As a general guideline, consider creating a structure when one or more of these conditions apply:

- The structure’s primary purpose is to encapsulate a few relatively simple data values.
- It is reasonable to expect that the encapsulated values will be copied rather than referenced when you assign or pass around an instance of that structure.
- Any properties stored by the structure are themselves value types, which would also be expected to be copied rather than referenced.
- The structure does not need to inherit properties or behavior from another existing type.

Examples of good candidates for structures include:

- The size of a geometric shape, perhaps encapsulating a `width` property and a `height` property, both of type `Double`.
- A way to refer to ranges within a series, perhaps encapsulating a `start` property and a `length` property, both of type `Int`.
- A point in a 3D coordinate system, perhaps encapsulating `x`, `y` and `z` properties, each of type `Double`.

In all other cases, define a class, and create instances of that class to be managed and passed by reference. In practice, this means that most custom data constructs should be classes, not structures.

## Assignment and Copy Behavior for Collection Types

Swift’s `Array` and `Dictionary` types are implemented as structures. However, arrays have slightly different copying behavior from dictionaries and other structures when they are assigned to a constant or variable, and when they are passed to a function or method.

The behavior described for `Array` and `Dictionary` below is different again from the behavior of `NSArray` and `NSDictionary` in Foundation, which are implemented as classes, not structures. `NSArray` and `NSDictionary` instances are always assigned and passed around as a reference to an existing instance, rather than as a copy.

> **NOTE**
>
> The descriptions below refer to the “copying” of arrays, dictionaries, strings, and other values. Where copying is mentioned, the behavior you see in your code will always be as if a copy took place. However, Swift only performs an *actual* copy behind the scenes when it is absolutely necessary to do so. Swift manages all value copying to ensure optimal performance, and you should not avoid assignment to try to preempt this optimization.

### Assignment and Copy Behavior for Dictionaries

Whenever you assign a `Dictionary` instance to a constant or variable, or pass a `Dictionary` instance as an argument to a function or method call, the dictionary is *copied* at the point that the assignment or call takes place. This process is described in [Structures and Enumerations Are Value Types](#structures-and-enumerations-are-value-types "Structures and Enumerations Are Value Types").

If the keys and/or values stored in the `Dictionary` instance are value types (structures or enumerations), they too are copied when the assignment or call takes place. Conversely, if the keys and/or values are reference types (classes or functions), the references are copied, but not the class instances or functions that they refer to. This copy behavior for a dictionary’s keys and values is the same as the copy behavior for a structure’s stored properties when the structure is copied.

The example below defines a dictionary called `ages`, which stores the names and ages of four people. The `ages` dictionary is then assigned to a new variable called `copiedAges` and is copied when this assignment takes place. After the assignment, `ages` and `copiedAges` are two separate dictionaries.

```swift
var ages = ["Peter": 23, "Wei": 35, "Anish": 65, "Katya": 19]
var copiedAges = ages
```

The keys for this dictionary are of type `String`, and the values are of type `Int`. Both types are value types in Swift, and so the keys and values are also copied when the dictionary copy takes place.

You can prove that the `ages` dictionary has been copied by changing an age value in one of the dictionaries and checking the corresponding value in the other. If you set the value for `"Peter"` in the `copiedAges` dictionary to `24`, the `ages` dictionary still returns the old value of `23` from before the copy took place:

```swift
copiedAges["Peter"] = 24
println(ages["Peter"])
// prints "23"
```

### Assignment and Copy Behavior for Arrays

The assignment and copy behavior for Swift’s `Array` type is more complex than for its `Dictionary` type. `Array` provides C-like performance when you work with an array’s contents and copies an array’s contents only when copying is necessary.

If you assign an `Array` instance to a constant or variable, or pass an `Array` instance as an argument to a function or method call, the contents of the array are *not* copied at the point that the assignment or call takes place. Instead, both arrays share the same sequence of element values. When you modify an element value through one array, the result is observable through the other.

For arrays, copying only takes place when you perform an action that has the potential to modify the *length* of the array. This includes appending, inserting, or removing items, or using a ranged subscript to replace a range of items in the array. If and when array copying does take place, the copy behavior for an array’s contents is the same as for a dictionary’s keys and values, as described in [Assignment and Copy Behavior for Dictionaries](#assignment-and-copy-behavior-for-dictionaries "Assignment and Copy Behavior for Dictionaries").

The example below assigns a new array of `Int` values to a variable called `a`. This array is also assigned to two further variables called `b` and `c`:

```swift
var a = [1, 2, 3]
var b = a
var c = a
```

You can retrieve the first value in the array with subscript syntax on either `a`, `b`, or `c`:

```swift
println(a[0])
// 1
println(b[0])
// 1
println(c[0])
// 1
```

If you set an item in the array to a new value with subscript syntax, all three of `a`, `b`, and `c` will return the new value. Note that the array is not copied when you set a new value with subscript syntax, because setting a single value with subscript syntax does not have the potential to change the array’s length:

```swift
a[0] = 42
println(a[0])
// 42
println(b[0])
// 42
println(c[0])
// 42
```

However, if you append a new item to `a`, you *do* modify the array’s length. This prompts Swift to create a new copy of the array at the point that you append the new value. Henceforth, `a` is a separate, independent copy of the array.

If you change a value in `a` after the copy is made, `a` will return a different value from `b` and `c`, which both still reference the original array contents from before the copy took place:

```swift
a.append(4)
a[0] = 777
println(a[0])
// 777
println(b[0])
// 42
println(c[0])
// 42
```

### Ensuring That an Array Is Unique

It can be useful to ensure that you have a unique copy of an array before performing an action on that array’s contents, or before passing that array to a function or method. You ensure the uniqueness of an array reference by calling the `unshare` method on a variable of array type. (The `unshare` method cannot be called on a constant array.)

If multiple variables currently refer to the same array, and you call the `unshare` method on one of those variables, the array is copied, so that the variable has its own independent copy of the array. However, no copying takes place if the variable is already the only reference to the array.

At the end of the previous example, `b` and `c` both reference the same array. Call the `unshare` method on `b` to make it become a unique copy:

```swift
b.unshare()
```

If you change the first value in `b` after calling the `unshare` method, all three arrays will now report a different value:

```swift
b[0] = -105
println(a[0])
// 777
println(b[0])
// -105
println(c[0])
// 42
```

### Checking Whether Two Arrays Share the Same Elements

Check whether two arrays or subarrays share the same storage and elements by comparing them with the identity operators (`===` and `!==`).

The example below uses the “identical to” operator (`===`) to check whether `b` and `c` still share the same array elements:

```swift
if b === c {
    println("b and c still share the same array elements.")
} else {
    println("b and c now refer to two independent sets of array elements.")
}
// prints "b and c now refer to two independent sets of array elements."
```

Alternatively, use the identity operators to check whether two subarrays share the same elements. The example below compares two identical subarrays from b and confirms that they refer to the same elements:

```swift
if b[0...1] === b[0...1] {
    println("These two subarrays share the same elements.")
} else {
    println("These two subarrays do not share the same elements.")
}
// prints "These two subarrays share the same elements."
```
### Forcing a Copy of an Array

Force an explicit copy of an array by calling the array’s `copy` method. This method performs a shallow copy of the array and returns a new array containing the copied items.

The example below defines an array called `names`, which stores the names of seven people. A new variable called `copiedNames` is set to the result of calling the `copy` method on the `names` array:

```swift
var names = ["Mohsen", "Hilary", "Justyn", "Amy", "Rich", "Graham", "Vic"]
var copiedNames = names.copy()
```

You can prove that the `names` array has been copied by changing an item in one of the arrays and checking the corresponding item in the other. If you set the first item in the `copiedNames` array to `"Mo"` rather than `"Mohsen"`, the `names` array still returns the old value of `"Mohsen"` from before the copy took place:

```swift
copiedNames[0] = "Mo"
println(names[0])
// prints "Mohsen"
```

> **NOTE**
>
> If you simply need to be sure that your reference to an array’s contents is the only reference in existence, call the `unshare` method, not the `copy` method. The `unshare` method does not make a copy of the array unless it is necessary to do so. The `copy` method always copies the array, even if it is already unshared.