All language subtitles for Swift Programming Tutorial – Full Course for Beginners - English (auto-generated) Vietnamese(Bilingual)

af Afrikaans
sq Albanian
am Amharic
ar Arabic
hy Armenian
az Azerbaijani
eu Basque
be Belarusian
bn Bengali
bs Bosnian
bg Bulgarian
ca Catalan
ceb Cebuano
ny Chichewa
zh-CN Chinese (Simplified)
zh-TW Chinese (Traditional)
co Corsican
hr Croatian
cs Czech
da Danish
nl Dutch
en English
eo Esperanto
et Estonian
tl Filipino
fi Finnish
fr French
fy Frisian
gl Galician
ka Georgian
de German
el Greek
gu Gujarati
ht Haitian Creole
ha Hausa
haw Hawaiian
iw Hebrew
hi Hindi
hmn Hmong
hu Hungarian
is Icelandic
ig Igbo
id Indonesian
ga Irish
it Italian
ja Japanese
jw Javanese
kn Kannada
kk Kazakh
km Khmer
ko Korean
ku Kurdish (Kurmanji)
ky Kyrgyz
lo Lao
la Latin
lv Latvian
lt Lithuanian
lb Luxembourgish
mk Macedonian
mg Malagasy
ms Malay
ml Malayalam
mt Maltese
mi Maori
mr Marathi
mn Mongolian
my Myanmar (Burmese)
ne Nepali
no Norwegian
ps Pashto
fa Persian
pl Polish
pt Portuguese
pa Punjabi
ro Romanian
ru Russian
sm Samoan
gd Scots Gaelic
sr Serbian
st Sesotho
sn Shona
sd Sindhi
si Sinhala
sk Slovak
sl Slovenian
so Somali
es Spanish
su Sundanese
sw Swahili
sv Swedish
tg Tajik
ta Tamil
te Telugu
th Thai
tr Turkish
uk Ukrainian
ur Urdu
uz Uzbek
vi Vietnamese Download
cy Welsh
xh Xhosa
yi Yiddish
yo Yoruba
zu Zulu
or Odia (Oriya)
rw Kinyarwanda
tk Turkmen
tt Tatar
ug Uyghur
Would you like to inspect the original subtitles? These are the user uploaded subtitles that are being translated: 1 00:00:00,000 --> 00:00:05,940 Swift là ngôn ngữ lập trình phổ biến thường được sử dụng để tạo ứng dụng iOS, đây là Swift is a popular programming language often used for creating iOS apps this is 2 00:00:05,940 --> 00:00:10,320 khóa học hoàn hảo để học Swift vandad hiện đang dạy khóa học này the perfect course for learning Swift vandad teaches this course he currently 3 00:00:10,320 --> 00:00:15,660 hoạt động với tư cách là Nhà phát triển iOS hàng đầu và anh ấy đã tạo ra nhiều khóa học phổ biến works as a lead iOS Developer and he's created many popular courses 4 00:00:15,660 --> 00:00:19,920 xin chào mọi người và chào mừng đến với khóa học này tên tôi là vandon và tôi là sinh viên năm cuối hi everyone and welcome to this course my name is vandon and I'm a senior full 5 00:00:19,920 --> 00:00:23,640 nhà phát triển ngăn xếp đến từ Thụy Điển trong khóa học này chúng ta sẽ nói về stack developer from Sweden in this course we're going to talk about 6 00:00:23,640 --> 00:00:28,140 Swift là ngôn ngữ lập trình không có pha trộn trong Mac OS hoặc iOS hoặc back-end Swift as a programming language without blending in Mac OS or iOS or back-end 7 00:00:28,140 --> 00:00:33,420 sự phát triển mà chúng ta sắp nói đến biến hằng cấu trúc enums development we're going to talk about variables constants structures enums 8 00:00:33,420 --> 00:00:37,860 các lớp học bạn đặt tên cho nó thậm chí là tương lai hiện đại của Swift làm ngôn ngữ chương trình như classes you name it even modern futures of Swift as a program language such as 9 00:00:37,860 --> 00:00:43,079 async và chờ đợi Tôi đang làm iOS phát triển bản thân từ cuối năm 2007 và async and await I've been doing iOS development myself since late 2007 and 10 00:00:43,079 --> 00:00:48,000 Tôi đã sử dụng Swift từ năm 2014 khi nó ra mắt công khai lần đầu tiên I've been using Swift since 2014 when it came out first publicly 11 00:00:48,000 --> 00:00:51,960 khóa học này được xây dựng cho những người đã quen thuộc với một chương trình khác this course is built for people who are already familiar with another program 12 00:00:51,960 --> 00:00:55,980 ngôn ngữ từ trước khi bạn không cần phải rất thành thạo ngôn ngữ đó language from before you don't have to be very proficient in that language that 13 00:00:55,980 --> 00:00:59,640 bạn đang sử dụng nhưng miễn là bạn biết cơ bản nó có thể là bản thảo python you're using but as long as you know the basics it could be python typescript 14 00:00:59,640 --> 00:01:03,600 JavaScript bị rỉ sét dù nó là gì nhưng như miễn là bạn đã quen với những điều cơ bản JavaScript rust whatever it is but as long as you're familiar with the basics 15 00:01:03,600 --> 00:01:07,680 vậy thì bạn nên đi đi bản thân video này là một phần của một video lớn hơn then you should be good to go this video itself is part of a bigger 16 00:01:07,680 --> 00:01:11,280 danh sách phát có sẵn trên của tôi Kênh YouTube và bạn có thể tìm thấy playlist which is available on my YouTube channel and which you can find 17 00:01:11,280 --> 00:01:15,659 chỉ bằng cách tìm kiếm tên của tôi và cái này danh sách phát mà tôi đang đề cập đến là just by searching for my name and this playlist which I'm referring to is 18 00:01:15,659 --> 00:01:19,439 được gọi là Full stack với Swift và Mục tiêu của danh sách phát chỉ là giúp chúng tôi called Full stack with Swift and the goal of the playlist is just to get us 19 00:01:19,439 --> 00:01:24,360 quen với việc phát triển Swift cho cả mặt trước và mặt sau vì vậy nếu familiar with doing Swift development for both front and and back end so if 20 00:01:24,360 --> 00:01:27,900 trong suốt khóa học này đôi khi tôi thực hiện tham chiếu đến danh sách phát này thì tại throughout this course I sometimes make references to this playlist then at 21 00:01:27,900 --> 00:01:32,520 ít nhất bạn cũng biết cái đó dùng để làm gì trước khi chúng ta bắt đầu, tôi thực sự cũng muốn least you know what that is for before we get started I'd really also 22 00:01:32,520 --> 00:01:35,759 đánh giá cao nếu bạn có thể cho tôi một theo dõi trên YouTube chỉ bằng cách tìm kiếm appreciate it if you could give me a follow on YouTube just by searching for 23 00:01:35,759 --> 00:01:39,299 tên tôi là liên kết mà bạn có thể tìm thấy trong phần mô tả ở cuối này my name the link to which you can find in the description at the bottom of this 24 00:01:39,299 --> 00:01:44,100 video và tôi cũng rất tích cực trên Twitter và Linkedin hàng ngày bằng cách xuất bản video and I'm also very active on Twitter and Linkedin daily by publishing 25 00:01:44,100 --> 00:01:48,180 mẹo và thủ thuật về lập trình ngôn ngữ và chỉ thông báo chung tips and tricks about programming languages and just generally informing 26 00:01:48,180 --> 00:01:53,220 công chúng về các ngôn ngữ như python bản thảo JavaScript rỉ sét Swift the public about languages such as python typescript JavaScript rust Swift 27 00:01:53,220 --> 00:01:59,220 bạn đặt tên cho nó như vậy mà không cần thêm Ado hãy bắt đầu nào chỉ cần bắt đầu với khóa học you name it so without further Ado let's just get started with the course 28 00:01:59,220 --> 00:02:04,020 xin chào mọi người và chào mừng đến với chương này đầy đủ với Swift trong chương này hi everyone and welcome to this chapter of full stack with Swift in this chapter 29 00:02:04,020 --> 00:02:10,080 chúng ta sẽ xem xét tất cả những gì hiện đại Các khái niệm có sẵn trong Swift dưới dạng we're going to look at all the modern Concepts that are available in Swift as 30 00:02:10,080 --> 00:02:13,980 một ngôn ngữ lập trình nếu bạn đã có lẽ bạn đã xem phần giới thiệu a programming language if you've already watched an introduction you probably 31 00:02:13,980 --> 00:02:19,500 biết điều đó và khóa học này nói chung không chỉ chương này mà cả khóa học này know that and that this course generally not just this chapter but this course 32 00:02:19,500 --> 00:02:24,420 nói chung là không dành cho người mới bắt đầu tuyệt đối vì vậy tôi hy vọng bạn đã biết một điều khác generally is not for absolute beginners so I expect you to already know another 33 00:02:24,420 --> 00:02:27,720 ngôn ngữ lập trình phải không nó có thể là gì không thực sự quan trọng programming language it doesn't it doesn't really matter what it is it can 34 00:02:27,720 --> 00:02:32,099 là con trăn rỉ sét, nó có thể là bản đánh máy JavaScript bất cứ điều gì miễn là bạn biết be python rust it can be typescript JavaScript whatever as long as you know 35 00:02:32,099 --> 00:02:36,420 những điều cơ bản của ngôn ngữ lập trình như vậy thì hàm và biến là gì the basics of programming languages such as what functions and variables are then 36 00:02:36,420 --> 00:02:41,280 bạn có thể đi nếu bạn không có thứ đó kinh nghiệm trước khóa học này you're good to go if you don't have that experience from before this course 37 00:02:41,280 --> 00:02:44,700 nói chung có thể là một chút bạn khó có thể theo kịp generally might be a little bit difficult for you to follow through with 38 00:02:44,700 --> 00:02:48,840 và tôi sẽ cố hết sức để giải thích tất cả mọi thứ nhưng vì tôi thực sự không and I will do my best to explain everything but since I I don't really 39 00:02:48,840 --> 00:02:54,420 muốn giải thích tất cả những điều cơ bản ừm tôi nghĩ có lẽ tốt nhất là bạn nên want to explain all the basics um I think it is best that you perhaps 40 00:02:54,420 --> 00:02:57,660 hãy xem một số hướng dẫn về cách nhận bắt đầu với một ngôn ngữ bị hỏng khác have a look at some guides on getting started with another broken language 41 00:02:57,660 --> 00:03:02,099 chẳng hạn như Python và sau đó bắt đầu với Tuy nhiên, khóa học này nếu bạn chưa such as Python and then get started with this course however if you haven't 42 00:03:02,099 --> 00:03:05,879 làm việc với bất kỳ ngôn ngữ chương trình nào khác từ trước và bạn cũng rất worked with any other program language from before and you're also very 43 00:03:05,879 --> 00:03:10,620 cũng tài năng và tôi cho rằng mọi người đều có thể bạn có thể talented as well and which I assume every everybody is you might be able to 44 00:03:10,620 --> 00:03:13,560 theo cùng với khóa học này mà không cần vấn đề follow along with this course without problem 45 00:03:13,560 --> 00:03:19,980 vậy điều chúng ta sẽ làm bây giờ là đi về phía trước và thiết lập một sân chơi về cơ bản so what we're gonna do now is to go ahead and set up a playground basically 46 00:03:19,980 --> 00:03:25,920 một không gian làm việc có nhiều sân chơi trong đó và sân chơi là khái niệm của Swift về a workspace with many playgrounds in it and playgrounds are Swift's concept of 47 00:03:25,920 --> 00:03:30,000 ngay lập tức có thể ngay lập tức xem những thay đổi của bạn là gì being immediate being able to immediately see what your changes are 48 00:03:30,000 --> 00:03:34,739 đang làm và về cơ bản nó sẽ cho phép bạn chạy mã của bạn tự động ngay khi doing and it will allow you to basically run your code automatically as soon as 49 00:03:34,739 --> 00:03:40,680 bạn thực hiện bất kỳ thay đổi nào đối với mã của mình để đó là một cách thử nghiệm rất hiệu quả you make any changes to your code so it is a very powerful way of testing 50 00:03:40,680 --> 00:03:45,239 mã hoặc thậm chí tạo một số dự án trong bạn có thể tạo ra một tổng thể code or even creating some projects in it you can you can create a whole 51 00:03:45,239 --> 00:03:49,319 dự án với một sân chơi và xem kết quả đồ họa ngay cả trên màn hình project with a playground and see the results graphically even on the screen 52 00:03:49,319 --> 00:03:53,879 vì vậy nó rất rất ừm mạnh mẽ đối với những người trong số các bạn so it's very very um powerful for those of you who are 53 00:03:53,879 --> 00:03:57,840 quen thuộc với ví dụ như rung động và phi tiêu bạn đã biết rằng bạn có thể nhìn thấy familiar for instance with flutter and dart you already know that you can see 54 00:03:57,840 --> 00:04:02,159 những thay đổi của bạn và hiển thị nó trên màn hình ngay lập tức và sân chơi là your changes and display it on the screen immediately and playgrounds are 55 00:04:02,159 --> 00:04:05,640 không khác gì họ rất giống nhau thực ra là về cách hoạt động của Phi tiêu và rung no different they're very similar actually to how Dart and flutter work 56 00:04:05,640 --> 00:04:10,379 nhưng thực ra đơn giản hơn một chút, tôi sẽ nói bởi vì chúng tôi đang viết thuần túy but a little bit actually simpler I would say because we're writing pure 57 00:04:10,379 --> 00:04:14,400 mã và chỉ nhìn thấy văn bản thuần túy được hiển thị trên màn hình là kết quả của code and just seeing pure text displayed on the screen as a result of for 58 00:04:14,400 --> 00:04:19,019 ví dụ gọi hàm vì vậy để tiếp tục việc này instance calling a function so in order to continue with this 59 00:04:19,019 --> 00:04:26,040 chương bạn có thể cần một chiếc Macintosh ừm tuy nhiên điều chúng tôi sắp làm là chapter you probably need a a Macintosh um however what we're going to do we're 60 00:04:26,040 --> 00:04:32,400 sẽ sử dụng nền tảng Swift và SDK ở đây hoặc thư viện để bạn có thể just going to use Swift foundation and SDK in here or a library so you can 61 00:04:32,400 --> 00:04:37,800 thực sự cũng làm theo trên Linux chẳng hạn như nếu bạn có Visual actually follow through as well on Linux such as if you have for instance Visual 62 00:04:37,800 --> 00:04:43,500 Thiết lập lại mã Studio và nếu có và bạn đã cài đặt Swift, bạn nên làm vậy Studio code re setup and if in and you've installed Swift you should be 63 00:04:43,500 --> 00:04:46,860 có thể làm theo chỉ sự khác biệt sẽ là những người trong số các bạn able to follow through the only difference will be that those of you who 64 00:04:46,860 --> 00:04:51,180 bạn đã cài đặt Macintosh và xcode sẽ có thể tạo ra một cách đơn giản have a Macintosh and xcode installed you will be able to create a simple 65 00:04:51,180 --> 00:04:54,960 sân chơi và xem những thay đổi của bạn ngay lập tức dành cho những bạn đang playground and see your changes immediately for those of you who are 66 00:04:54,960 --> 00:04:59,820 theo dõi điều này trên Linux và trực quan mã studio chẳng hạn bạn cần chạy following this on Linux and visual studio code for instance you need to run 67 00:04:59,820 --> 00:05:05,240 mã theo cách thủ công nên bạn sẽ cần phải chỉ cần nhập mã của bạn và sau đó gọi Swift the code manually so you will need to just type your code and then call Swift 68 00:05:05,240 --> 00:05:10,919 trình biên dịch từ thiết bị đầu cuối của bạn và chúng tôi là một bảng điều khiển để chạy chúng compiler from from your terminal and we're a console in order to run those 69 00:05:10,919 --> 00:05:14,520 mã nên nó không khác nhau vì vậy bạn có thể làm theo codes so it shouldn't be that different so you should be able to follow along 70 00:05:14,520 --> 00:05:19,919 ngay cả trên máy Linux nên không có hơn nữa Ado hãy tiếp tục và even on a Linux machine so without further Ado let's just go ahead and 71 00:05:19,919 --> 00:05:24,840 tạo không gian làm việc của chúng tôi bây giờ tôi sẽ giải thích không gian làm việc thực sự là không gian làm việc create our workspace now I'll explain what a workspace really is a workspace 72 00:05:24,840 --> 00:05:29,520 là tập hợp các dự án chuyên nghiệp mà bạn có thể nói một tập hợp các tập tin và is a collection of pro projects you could say a collection of files and 73 00:05:29,520 --> 00:05:34,680 dự án, nó thực sự chỉ là một tập tin điều đó giải thích cấu trúc của một dự án projects it's it's really just one file that explains the structure of a project 74 00:05:34,680 --> 00:05:40,440 sang xcode nếu bạn đang chạy mọi thứ trên Linux nên bạn không cần phải to xcode if you're if you're running things on Linux so you don't have to 75 00:05:40,440 --> 00:05:45,000 tạo một không gian làm việc mà có lẽ bạn không thể bởi vì xcode làm điều đó và create a workspace you probably can't because xcode does that and 76 00:05:45,000 --> 00:05:48,840 Thật không may, xcode này ừm rõ ràng là ứng dụng xcode tạo ra unfortunately this xcode um obviously xcode application creates 77 00:05:48,840 --> 00:05:54,960 giống như một định dạng độc quyền cho tất cả loại tập tin không phải là tập tin văn bản mà là like a proprietary format for all of its files kind of so not the text files but 78 00:05:54,960 --> 00:06:01,199 như không gian làm việc và các tập tin dự án chúng là định dạng XML độc quyền like the workspace and project files they are proprietary XML format which is 79 00:06:01,199 --> 00:06:07,020 Y khó hiểu trong thời đại ngày nay nó phải thực sự sử dụng XML nhưng ừm puzzling Y in this day and age it has to use XML really but um 80 00:06:07,020 --> 00:06:11,820 đó là một chủ đề khác vì vậy nếu bạn theo dõi xuyên suốt và cùng với khóa học tại that's a different subject so if you're following through and with the course at 81 00:06:11,820 --> 00:06:17,460 về nhà với Linux thì bạn không cần phải tạo không gian làm việc này nhưng nếu bạn đang ở home with Linux then you don't have to create this workspace but if you're at 82 00:06:17,460 --> 00:06:21,120 về nhà với một chiếc Macintosh bạn cần phải đi phía trước và cùng nhau tạo không gian làm việc này home with a Macintosh you need to go ahead and create this workspace together 83 00:06:21,120 --> 00:06:24,960 với tôi vì vậy tôi sẽ đề cập đến phần bổ sung của mình with me so I'm going to bring up my extra just 84 00:06:24,960 --> 00:06:28,259 đủ ở đây để chúng ta có thể thấy những gì chúng tôi đang làm. Tôi sẽ chuyển sang nơi mới và enough in here so that we can see what we're doing I'm going to go to new and 85 00:06:28,259 --> 00:06:33,180 hãy nói không gian làm việc thì ở đây hãy nói Swift và let's just say workspace then in here let's just say Swift and 86 00:06:33,180 --> 00:06:39,660 khóa học cấp tốc YouTube ổn ở đây và giả sử hãy lưu không gian làm việc này dưới dạng crash course YouTube okay in here and let's just say save this workspace as 87 00:06:39,660 --> 00:06:42,960 bạn có thể thấy đó chỉ là một không gian làm việc trống rỗng tại thời điểm này nên nó không có bất kỳ you can see it's just an empty workspace at the moment so it doesn't have any 88 00:06:42,960 --> 00:06:45,960 nội dung những gì chúng ta sẽ làm sau đó hãy chỉ contents what we're going to do then let's just 89 00:06:45,960 --> 00:06:49,020 tăng kích thước của cái này nên cần toàn bộ màn hình increase the size of this so it takes the entire screen 90 00:06:49,020 --> 00:06:55,139 và sau đó chúng ta sẽ tiếp tục trong hồ sơ mới và sau đó chúng ta sẽ đi vào một and then we're going to go ahead in file new and then we're going to go into a 91 00:06:55,139 --> 00:06:59,280 tài liệu và ở đây gõ sân chơi vào file and in here type playground in the 92 00:06:59,280 --> 00:07:04,680 trường tìm kiếm và thêm một khoảng trống mới sân chơi được rồi search field and add a new blank playground okay 93 00:07:04,680 --> 00:07:09,539 vì vậy khái niệm đầu tiên mà chúng ta sắp thực hiện nói về ở đây sẽ được gọi là so the first concept that we're going to talk about in here is going to be called 94 00:07:09,539 --> 00:07:13,740 các biến vì vậy hãy chỉ nói các biến và tôi có thể thấy rằng không gian làm việc của chúng tôi variables so let's just say variables and I can see that our workspace was 95 00:07:13,740 --> 00:07:18,539 thực ra chỉ tạo ở đây mà không có bất kỳ thư mục để chúng tôi có thể khắc phục actually just creating here without any folder so we might be able to remedy 96 00:07:18,539 --> 00:07:23,160 trước khi chúng ta nhấp vào hãy tạo sân chơi hãy để tôi tiếp tục và mở that before we click create our playground let me just go ahead and open 97 00:07:23,160 --> 00:07:28,500 có một cửa sổ tìm kiếm ở đây nên chúng ta hãy bắt đầu thôi phía trước ở đây a finder window in here so let's just go ahead in here 98 00:07:28,500 --> 00:07:33,479 bạn không thực sự thấy những gì tôi đang làm nhưng ngay đây là thư mục thì tôi you don't see actually what I'm doing but right here is the folder then I'm 99 00:07:33,479 --> 00:07:37,560 sẽ lấy một cái tôi sẽ tạo ra một cái thư mục ở đây giả sử Swift going to take a I'm going to create a folder in here let's let's say Swift 100 00:07:37,560 --> 00:07:42,419 khóa học cấp tốc YouTube và đặt cái này và sau đó chúng ta có thể đóng crash course YouTube and place this and and then we can close 101 00:07:42,419 --> 00:07:47,400 xcode của chúng tôi đặt không gian làm việc vào đó và chúng ta hãy nhấp đúp chuột vào our xcode place the workspace in there and let's just double click on the 102 00:07:47,400 --> 00:07:51,840 không gian làm việc để mở xcode của chúng tôi nên bây giờ tất cả những sân chơi mà chúng ta sắp đến workspace to open our xcode so now all the playgrounds that we're going to 103 00:07:51,840 --> 00:07:55,979 create sẽ được tạo bên trong thư mục đó được rồi, hãy tiếp tục và create are going to be creating inside that folder okay so let's go ahead and 104 00:07:55,979 --> 00:08:02,819 tạo các biến của chúng tôi cho một sân chơi từ đầu nên tập tin mới được rồi và create our variables for a playground from scratch so file new file okay and 105 00:08:02,819 --> 00:08:05,639 thì ở đây chúng ta sẽ nói sân chơi và bạn thực sự có thể tìm thấy then in here we're going to say playground and you can actually find 106 00:08:05,639 --> 00:08:09,960 sân chơi ở đây thấp hơn một chút, tôi hãy nghĩ như ở đâu đó bạn có thể thấy ở đây playground a little bit lower in here I think as somewhere in here you can see 107 00:08:09,960 --> 00:08:14,400 trong phần sân chơi nên hãy nói sân chơi trống và hãy gọi in the playground section so let's say blank playground and let's call the 108 00:08:14,400 --> 00:08:18,539 các biến được rồi vì chúng ta sẽ nói về các biến bây giờ variables okay because we're going to talk about variables now 109 00:08:18,539 --> 00:08:22,919 vì vậy đây là điều mặc định mà bạn có thể thấy ở đây và về cơ bản đây là so this is the default thing that you can see in here and basically this is 110 00:08:22,919 --> 00:08:27,660 chế độ xem của bạn, bạn có thể thấy Màn hình trắng hơn ở đây đơn giản vì có lẽ bạn your view you might see A Whiter screen in here simply because well maybe you 111 00:08:27,660 --> 00:08:30,539 chưa thay đổi chủ đề của bạn trong xcode và đó là điều mà bạn có thể tìm ra haven't changed your themes in xcode and that's something that you can figure out 112 00:08:30,539 --> 00:08:33,839 tự mình làm thế nào để thay đổi chủ đề và thoát ra chúng ta sẽ không nói về điều đó on your own how to change themes and exit we're not going to talk about that 113 00:08:33,839 --> 00:08:37,979 được rồi hãy làm rõ điều này và thay vì việc nhập bộ giao diện người dùng mà chúng tôi sắp thực hiện okay let's clear this and instead of importing UI kit we're going to just 114 00:08:37,979 --> 00:08:41,880 nhập khẩu kem nền và nếu bạn đang xem khóa học này ở nhà hoặc bất cứ nơi nào bạn ở import foundation and if you're watching this course at home or wherever you're 115 00:08:41,880 --> 00:08:46,860 xem cái này trên Linux chẳng hạn và nếu bạn không có Mac OS, bạn cần watching this on Linux for instance then and if you don't have a Mac OS you need 116 00:08:46,860 --> 00:08:50,279 để làm điều tương tự chỉ cần nhập Foundation chỉ cần tạo một Swift đơn giản to also do the same thing just import Foundation just create a simple Swift 117 00:08:50,279 --> 00:08:54,180 tập tin bạn không cần phải tạo một sân chơi chỉ cần nhấp vào tạo một đồng bằng file you don't have to create a playground just click create a plain 118 00:08:54,180 --> 00:08:59,640 văn bản tệp Dot Swift rồi nhập Thư viện Foundation ở đây nhé text Dot Swift file and then import Foundation library in here okay 119 00:08:59,640 --> 00:09:01,820 nước ngoài foreign 120 00:09:02,420 --> 00:09:07,680 nền tảng và nền tảng bao gồm tất cả cơ bản như tên gọi của nó cho thấy nó foundation and Foundation includes all the basic as its name indicates it 121 00:09:07,680 --> 00:09:12,720 bao gồm tất cả những điều cơ bản về Swift chứa thực sự thích cách hoạt động của chuỗi includes all the basics of what Swift contains really like how strings work 122 00:09:12,720 --> 00:09:17,399 cách các số nguyên hoạt động theo mặc định hoạt động giữa những khác nhau này how integers work all the default operations between these different 123 00:09:17,399 --> 00:09:22,980 các biến và thậm chí cả các tùy chọn, v.v. cơ sở nhập khẩu là một trong những cơ sở variables and even optionals Etc so importing foundations is one of the most 124 00:09:22,980 --> 00:09:28,019 ừ, những điều quan trọng về cơ bản bạn có thể làm trong tệp Swift của bạn như chính bạn important uh things you can do basically in your Swift file as you're as you're 125 00:09:28,019 --> 00:09:34,080 học Swift được rồi chúng ta hãy tiếp tục và nói về getting to learn Swift okay so let's go ahead and talk about 126 00:09:34,080 --> 00:09:38,940 biến trong Swift Có hai cú pháp hoặc từ khóa khác nhau cho variables in Swift There are two different syntaxes or keywords for 127 00:09:38,940 --> 00:09:44,220 tạo biến Một người đang sử dụng let và cái còn lại là tạo một biến creating variables One is using a let and the other is creating a variable 128 00:09:44,220 --> 00:09:51,180 sử dụng VAR vì vậy hãy để và VAR sự khác biệt giữa những điều này rất khó hiểu đối với một số người using VAR so let and VAR the difference between these is very confusing for some 129 00:09:51,180 --> 00:09:56,760 mọi người và họ nghĩ rằng hãy để tạo ra sự bất biến và VAR tạo ra một people and that they think that let creates immutability and VAR creates a 130 00:09:56,760 --> 00:09:59,880 tính biến đổi tuy nhiên điều duy nhất khác biệt giữa mutability however the only thing different between 131 00:09:59,880 --> 00:10:06,899 hai điều này là biến let không thể được chỉ định lại trong khi VAR có thể these two is that a let variable cannot be assigned to again whereas a VAR can 132 00:10:06,899 --> 00:10:11,100 được giao lại và còn một số nhỏ khác be assigned to again and there are some other small 133 00:10:11,100 --> 00:10:15,480 sự khác biệt giữa chúng, ý tôi là chúng ta sẽ thực sự nhìn vào những thứ đó và differences between them such I mean we will actually look at those things and 134 00:10:15,480 --> 00:10:19,500 khi chúng tôi làm việc với các lớp học cho thể hiện hoặc cấu trúc chúng khác nhau như thế nào when we're working with classes for instance or structures how they differ 135 00:10:19,500 --> 00:10:24,420 từ nhau và bây giờ chỉ biết rằng chúng ta không thể được chỉ định cho from each other and but for now just know that let's cannot be assigned to 136 00:10:24,420 --> 00:10:28,320 nhiều lần có thể được chỉ định cho một trò chơi nhưng cũng nên nhớ rằng có again and far can be assigned to a game but also keep in mind that there are 137 00:10:28,320 --> 00:10:33,180 một số khác biệt nhỏ khác giữa chúng tôi sẽ giải thích được rồi, vậy hãy cùng some other small differences between them which we'll explain okay so let's 138 00:10:33,180 --> 00:10:39,300 hãy vào đây và nói tên tôi và sau đó chúng tôi nói bằng Lambda cho go ahead in here and say let's my name and then we say equal to Lambda for 139 00:10:39,300 --> 00:10:44,640 ví dụ và sau đó chúng tôi nói hãy để tên của bạn Foo có ổn không sau khi bạn làm xong những việc này và instance and then we say let your name is Foo okay after you've done these and 140 00:10:44,640 --> 00:10:49,079 đã tạo hai biến này bạn không thể giao lại cho họ đơn giản chỉ vì created these two variables you cannot assign to them again simply because 141 00:10:49,079 --> 00:10:55,200 có ít biến hơn nên hãy nói rằng tên là tên của bạn và nếu chúng ta đi xuống đây there are less variables so let's say my name is your name and if we go down here 142 00:10:55,200 --> 00:10:59,040 ở cuối màn hình bạn có thể thấy con chuột của tôi và tôi sẽ giữ cái này at the bottom of the screen you can see my mouse and I'm going to hold on this 143 00:10:59,040 --> 00:11:03,060 nên tôi sẽ nhấn nút theo dõi đường dẫn và sau đó nói tự động button so I'm just going to press my track path and then say automatically 144 00:11:03,060 --> 00:11:07,200 chạy và điều này sẽ chỉ đảm bảo rằng điều này sân chơi sẽ được tự động run and this will just ensure that this playground will be automatically 145 00:11:07,200 --> 00:11:12,000 được thực hiện bất cứ lúc nào chúng tôi thay đổi bất cứ điều gì trong được rồi bạn có thể thấy lỗi nó báo executed anytime we change anything in it okay you can see the error it says 146 00:11:12,000 --> 00:11:18,120 không thể gán giá trị tên tôi là một hằng số let nên đó là cách bạn biết that cannot assign the value my name is a let constant so that's how you know 147 00:11:18,120 --> 00:11:23,399 mà bạn không thể gán lại cho nó sau tạo một hằng số bạn chỉ cần that you cannot assign to it again after creating a let constant you just need to 148 00:11:23,399 --> 00:11:28,140 để nó đi, bạn không cần, bạn không thể về cơ bản gán một giá trị mới cho nó nhé leave it you don't have to you you can't basically assign a new value to it okay 149 00:11:28,140 --> 00:11:35,160 vậy đó là cách chúng ta hãy làm việc bây giờ hãy đi nào phía trước và tạo một biến nên bây giờ so that's how let's works now let's go ahead and create a variable so for now 150 00:11:35,160 --> 00:11:39,480 chúng ta sẽ tạo ra một thứ đơn giản mảng và đã cho rằng bạn biết we're just going to create a simple array and already assume that you know 151 00:11:39,480 --> 00:11:43,019 mảng là gì nhưng chúng ta sẽ nói chuyện về các bộ sưu tập một lát sau what arrays are but we're going to talk about collections a little bit later 152 00:11:43,019 --> 00:11:47,279 chỉ cần biết rằng trong Swift bạn tạo một mảng với cú pháp này với hình vuông just know that in Swift you create an array with this syntax with square 153 00:11:47,279 --> 00:11:54,120 dấu ngoặc được rồi vì vậy hãy nói tên VAR là chúng ta sẽ nói Khai thác và tên của bạn brackets okay so let's say VAR names is we're going to say Mining and your name 154 00:11:54,120 --> 00:11:59,640 được rồi vì vậy chúng tôi vừa tạo một mảng ở đây và sau đó bạn có thể xem kết quả okay so we just created an array in here and you can then see the results to the 155 00:11:59,640 --> 00:12:03,959 phía bên phải bạn có thể thấy mảng này chứa van Dot và foo được rồi right hand side you can see this array contains van Dot and a foo okay 156 00:12:03,959 --> 00:12:08,040 bây giờ bạn có thể tiếp tục và nói vì đây là một biến thì nó có thể now you can go ahead then and say since this is a variable then it can be 157 00:12:08,040 --> 00:12:13,680 bị đột biến ngay cả bên trong nếu nó chứa ví dụ như một cấu trúc nên chúng ta nói tên mutated even internally if it contains for instance a structure so we say names 158 00:12:13,680 --> 00:12:18,180 và sau đó chúng ta có thể gọi hàm chắp thêm trên đó và chúng ta nói thanh và sau đó chúng ta có thể and then we can call an append function on it and we say bar and then we can 159 00:12:18,180 --> 00:12:23,399 cũng thêm bồn tắm vào đó như bạn có thể thấy trong ở đây vậy nên đến cuối chuyện này thì chúng ta also add baths to it as you can see in here so by the end of this then our 160 00:12:23,399 --> 00:12:29,339 mảng được gọi là tên chứa Found.foobar và âm trầm tuy nhiên nếu bạn thay đổi điều này thành array called names contains found.foobar and bass however if you change this to a 161 00:12:29,339 --> 00:12:34,399 để bạn thấy rằng chúng tôi sẽ nhận được một ít lỗi ở đây nói rằng đây là một sự cho phép let you will see that we'll get some errors in here saying that this is a let 162 00:12:34,399 --> 00:12:41,120 hằng số không thể sử dụng thành viên đột biến trên tên giá trị bất biến bây giờ cái này chuyển sang constant cannot use mutating member on immutable value names now this goes to 163 00:12:41,120 --> 00:12:46,620 điều này đi sâu hơn một chút về cách hãy để mvar khác biệt với nhau this goes a little bit deeper in how let's mvar are different from each other 164 00:12:46,620 --> 00:12:51,120 nhưng để hiểu được điều đó chúng ta cần để hiểu cấu trúc là gì but in order to understand that we need to understand what structures are 165 00:12:51,120 --> 00:12:56,399 bởi vì mảng trong Swift theo mặc định là cấu trúc nếu bạn không sử dụng cấu trúc cũ because arrays in Swift by default are structures if you're not using old 166 00:12:56,399 --> 00:13:02,339 Ví dụ như mảng C mục tiêu, vì vậy chỉ cần biết điều đó bằng cách tạo một mảng biến Objective C arrays for instance so just know that by creating a variable array 167 00:13:02,339 --> 00:13:06,180 bạn có thể nối vào nó và bạn có thể xóa ví dụ như những thứ từ nó như chúng ta sẽ thấy you can append to it and you can remove stuff from it for instance as we'll see 168 00:13:06,180 --> 00:13:11,880 tuy nhiên sau này nếu điều này được phép thì bạn không thể thay đổi ngay cả các giá trị bên trong later however if this is let you cannot mutate even the internal values inside 169 00:13:11,880 --> 00:13:17,279 nó để bạn có thể thấy có hai khái niệm về khả năng thay đổi trong Swift là it so you can see there are two mutability concepts in in Swift one is 170 00:13:17,279 --> 00:13:21,120 rằng bạn thực sự có thể thay đổi mảng này ví dụ bạn có thể nói tên là that you can actually mutate this array for instance you can say names is 171 00:13:21,120 --> 00:13:25,920 hoàn toàn bằng một biến khác đúng luật nhé completely equal to another variable like the law okay 172 00:13:25,920 --> 00:13:30,839 nên bạn có thể thấy đột nhiên nó trở thành blah blah bar bass bạn thấy đấy, đây là so you can see all of a sudden it became blah blah bar bass you see so this is 173 00:13:30,839 --> 00:13:36,000 biến đổi chính biến đó là thực sự đã được gán một mảng hoàn toàn mới mutating the variable itself it is actually assigned a complete new array 174 00:13:36,000 --> 00:13:42,360 đặt tên như một biến và hai cái này các câu lệnh đang làm thay đổi những gì bên trong to names as a variable and these two statements are mutating what is inside 175 00:13:42,360 --> 00:13:48,839 biến này nên thực hiện let in ở đây ngăn chặn cả việc gán một giá trị mới cho this variable so doing a let in here prevents both assigning a new value to 176 00:13:48,839 --> 00:13:54,660 tên và cả tên đột biến tuy nhiên có VAR bạn có thể chỉ định names and also mutating names however having a VAR you can assign a 177 00:13:54,660 --> 00:14:00,839 biến mới có hai tên và bạn cũng có thể thay đổi tên nội bộ được rồi nên đây là new variable two names and you can also mutate names internally okay so this is 178 00:14:00,839 --> 00:14:07,320 một sự khác biệt khác giữa let và VAR vì vậy nó cũng rất rất quan trọng để another difference between let and VAR so it is also very very important to 179 00:14:07,320 --> 00:14:13,860 hiểu hai điểm khác biệt này sự đột biến của biến bên trong và understand these two differences mutation of the variable internally and 180 00:14:13,860 --> 00:14:18,839 gán một giá trị mới cho biến thay đổi nó rất nhiều nhà phát triển assigning a new value to the variable to mutate it so a lot of developers 181 00:14:18,839 --> 00:14:22,320 đấu tranh với điều đó đặc biệt là trong bắt đầu nên tôi hoàn toàn hiểu nếu struggle with that especially in the beginning so I completely understand if 182 00:14:22,320 --> 00:14:27,120 có một chút khó khăn để bắt đầu nhưng bạn càng học điều này sớm it is a little bit difficult to start with but the earlier you learn this 183 00:14:27,120 --> 00:14:32,639 khái niệm thì càng tốt vì nếu không thì tôi nghĩ rằng việc làm swift có thể trở nên khá khó khăn concept the better because otherwise I think a swift can become quite difficult 184 00:14:32,639 --> 00:14:39,779 để bạn hiểu về tương lai vì vậy hãy dành chút thời gian và thử nghiệm một for for you to understand going forward so spend some time and experiment with a 185 00:14:39,779 --> 00:14:44,220 hãy và VAR nhưng chúng ta sẽ có khá nhiều rất nhiều ví dụ trong chương này vì vậy bạn let's and VAR but we will have quite a lot of examples in this chapter so you 186 00:14:44,220 --> 00:14:48,779 không cần phải làm việc đó một mình nhé Vì thế don't have to do it on your own okay so 187 00:14:48,779 --> 00:14:55,019 bây giờ nếu bạn thay đổi một biến như if bạn đã tạo một biến và bạn gán now if you change a variable like if you've created a variable and you assign 188 00:14:55,019 --> 00:15:01,320 một giá trị mới cho nó và nó sẽ không thay đổi đối tượng ban đầu a new value to it and it won't it won't change the object that it originally was 189 00:15:01,320 --> 00:15:05,339 được giao bây giờ tôi sẽ giải thích điều đó là gì thực sự có nghĩa là vì vậy hãy nói hãy Foo assigned to now I will explain what that actually means so let's say let's Foo 190 00:15:05,339 --> 00:15:11,399 hãy tạo một không gian khác ở đây nào nói Foo là Foop và sau đó chúng ta nói VAR Foo let's create another space in here let's say Foo is foop and then we say VAR Foo 191 00:15:11,399 --> 00:15:17,160 2 bằng foop như thế này nhé bạn bây giờ có thể thấy biến đồ ăn này 2 2 is equal to foop like this okay you can see now this variable of food 2 192 00:15:17,160 --> 00:15:22,260 chứa giá trị bên trong Foo được rồi và bạn có thể thấy cả hai đều chứa contains the value inside Foo all right and you can see both of them contain the 193 00:15:22,260 --> 00:15:27,839 chuỗi Foo ngay bây giờ nếu bạn tiếp tục và thiết lập giá trị của Foo 2 chẳng hạn như Foo 2 string Foo now if you go ahead and set the value of Foo 2 to for instance Foo 2 194 00:15:27,839 --> 00:15:33,540 như thế này bạn có thể thấy Foo và futu vẫn chứa các giá trị mà bạn muốn like this you can see that Foo and futu still contain the values that you'd 195 00:15:33,540 --> 00:15:39,959 mong đợi Foo chứa thức ăn và thức ăn 2 chứa giá trị mới nên bằng cách gán một expect Foo contains food and food 2 contains the new value so by assigning a 196 00:15:39,959 --> 00:15:45,660 giá trị mới cho Thực phẩm 2 trước đây bằng Foo bạn không ghi đè new value to Food 2 which was previously equal to Foo you're not overwriting the 197 00:15:45,660 --> 00:15:49,500 giá trị bên trong Foo đơn giản chỉ vì cái này đang đề cập đến cái này value that was inside Foo simply because this is referring to this 198 00:15:49,500 --> 00:15:53,699 và lý do đằng sau điều này là chúng tôi đang làm việc với một thứ gọi là and the reasoning behind this is that we're working with something called 199 00:15:53,699 --> 00:15:59,160 các loại giá trị bây giờ tôi sẽ giải thích thêm các loại giá trị sau nhưng tất cả những gì bạn cần value types now I will explain more value types later but all you need to 200 00:15:59,160 --> 00:16:06,180 biết bây giờ là bằng cách chỉ định giá trị của Foo to Foo đối với chúng ta chỉ đơn giản là know for now is that by assigning the value of Foo to Foo to we're simply 201 00:16:06,180 --> 00:16:12,000 sao chép giá trị này sang futu vì vậy giá trị này đang được sao chép hoàn toàn copying this value over to futu so this value is being completely copied 202 00:16:12,000 --> 00:16:17,579 và bạn đang tạo một phiên bản mới của nó bên trong thức ăn cũng vậy nên bây giờ chúng ta có hai Foos and you're creating a new instance of it inside food too so now we have two Foos 203 00:16:17,579 --> 00:16:23,760 bên trong bộ nhớ vào thời điểm này vì vậy chúng tôi không nhận được tài liệu tham khảo nên nó inside memory by this point so we're not getting a reference so it's 204 00:16:23,760 --> 00:16:26,220 không phải là loại tài liệu tham khảo mà chúng ta đang nói đến Về not a reference type that we're talking about 205 00:16:26,220 --> 00:16:30,959 Swift có các loại giá trị và tham chiếu các loại tài liệu tham khảo cho những người bạn Swift has value types and reference reference types for those of you who are 206 00:16:30,959 --> 00:16:33,959 không quen với khái niệm này từ trước khi đừng lo lắng về điều đó tôi sẽ giải thích not familiar with this concept from before don't worry about it I'll explain 207 00:16:33,959 --> 00:16:37,440 nó chi tiết hơn nhưng dành cho những người trong số các bạn những người quen thuộc với khái niệm này chỉ it more in details but for those of you who are familiar with this concept just 208 00:16:37,440 --> 00:16:41,820 biết rằng các cấu trúc cơ bản về cơ bản như know that structures which are basic basically as 209 00:16:41,820 --> 00:16:47,220 Chuỗi Swift là một loại cấu trúc nó trong các cấu trúc về cơ bản là giá trị Swift string is a type of structure it in structures are basically value 210 00:16:47,220 --> 00:16:51,240 các loại và sau đó chúng tôi cũng có các lớp học và đó là các loại tham chiếu và chúng tôi sẽ types and then we also have classes and which are reference types and we'll 211 00:16:51,240 --> 00:16:56,399 giải thích tất cả những điều này sau trong tương lai nhưng chỉ cần biết rằng bằng cách gán một giá trị explain all of these later in the future but just know that by assigning a value 212 00:16:56,399 --> 00:17:02,699 được gán cho một biến sẽ hãy gán nó cho một biến như thế này that was assigned to a variable would let assigning it to a variable like this 213 00:17:02,699 --> 00:17:08,819 bằng VAR và sau đó thay đổi giá trị của biến đó và gán một giá trị mới with VAR and then changing the value of that variable and assigning a new value 214 00:17:08,819 --> 00:17:13,980 với biến đó bạn sẽ không thay đổi giá trị được gán cho biến đó to that variable you're not changing the value that was assigned to that variable 215 00:17:13,980 --> 00:17:17,160 ban đầu tôi biết ý tôi là thế này câu này hơi phức tạp một chút nhưng initially I know that I mean this the sentence is a little bit complicated but 216 00:17:17,160 --> 00:17:22,260 Tôi nghĩ tôi nghĩ bạn hiểu được điểm của tôi đây là điều tôi đang cố nói được rồi I think I think you get my points in here what I'm trying to say okay 217 00:17:22,260 --> 00:17:27,360 bây giờ chúng ta có thể nhìn vào cái khác ví dụ về điều này và nó trông như thế nào now we can have a look at another example of this and how that looks so 218 00:17:27,360 --> 00:17:32,040 hãy tiếp tục và nói hãy thêm nhiều cái tên nữa và hãy tạo một mảng ở đây và let's go ahead and say let's more names and let's create an array in here and 219 00:17:32,040 --> 00:17:38,820 sau đó chúng ta nói Foo và sau đó là một quán bar được rồi sau đó giả sử chúng ta tạo một bản sao của then we say Foo and then a bar okay then let's let's say we create a copy of 220 00:17:38,820 --> 00:17:44,580 chúng tôi nói rằng một bản sao có nhiều tên hơn và đơn giản vì đây là biến let it we say a copy is more names and simply because this is a let's variable 221 00:17:44,580 --> 00:17:51,120 và chúng tôi cũng đang làm việc với Swift mảng là một cấu trúc thì chúng ta and also that we're working with a swift array which is a structure then we 222 00:17:51,120 --> 00:17:56,580 nên biết rằng cấu trúc có giá trị các loại và gán giá trị của a should know that structures are value types and assigning the value of a 223 00:17:56,580 --> 00:18:02,220 cấu trúc này sang cấu trúc khác hãy thay đổi ở đây tạo một bản sao của toàn bộ mảng này structure to another let's variable in here creates a copy of this entire array 224 00:18:02,220 --> 00:18:07,679 đối với chúng tôi thì ổn nên bây giờ chúng tôi xin lỗi hãy biến nó thành một biến sao chép for us okay so now that we have sorry let's make this a copy variable 225 00:18:07,679 --> 00:18:13,320 về cơ bản bây giờ chúng ta hãy đi và thêm một số giá trị cho cảnh sát này một biến được sao chép và basically let's now go and add some value to this cop a copied variable and 226 00:18:13,320 --> 00:18:18,059 nói nối thêm và chúng tôi nói Bas được rồi và sau đó chúng ta nói hãy lấy giá trị của nhiều hơn say append and we say Bas all right and then we say let's get the value of more 227 00:18:18,059 --> 00:18:23,640 tên rồi copy bạn có thể xem thêm tên ở đây vẫn chứa Foo và bar names and then the copy you can see more names in here still contains Foo and bar 228 00:18:23,640 --> 00:18:29,160 tuy nhiên đó là những giá trị ban đầu họ đã sao chép biến bây giờ chứa which were the original values however they copied the variable now contains 229 00:18:29,160 --> 00:18:34,500 âm trầm như bạn có thể thấy ở đây vì vậy hãy thêm Beth cho bản sao này không thay đổi bass as you can see in here so adding Beth to this copy did not change the 230 00:18:34,500 --> 00:18:40,679 các giá trị nằm bên trong nhiều tên hơn và điều này một lần nữa quay trở lại tốc độ nhanh như thế nào values that were inside more names and this again goes back to how swift is 231 00:18:40,679 --> 00:18:45,600 làm việc với các loại giá trị ở đây sao chép nội dung của nhiều tên hơn working with value types in here it is copying over the contents of more names 232 00:18:45,600 --> 00:18:51,000 vào biến sao chép này và thay đổi dữ liệu nội bộ của biến này không into this copy variable and changing this variable's internal data does not 233 00:18:51,000 --> 00:18:56,340 ảnh hưởng đến dữ liệu ban đầu được giao ngay từ đầu được rồi affect the original data which it was assigned to in the beginning okay so 234 00:18:56,340 --> 00:19:01,799 hy vọng bây giờ điều đó có ý nghĩa bây giờ có một điều có thể là một chút hopefully that makes sense by now now one thing that can be a little bit 235 00:19:01,799 --> 00:19:09,419 khó hiểu đối với các nhà phát triển là khi nào họ đang làm việc với let M VAR nhưng với confusing for developers is when when they're working with let M VAR but with 236 00:19:09,419 --> 00:19:15,120 các lớp Objective C cũ được rồi và điều này có thể hơi lạ đối với old Objective C classes all right and this this can be a little bit strange to 237 00:19:15,120 --> 00:19:19,740 bắt đầu với giống như nhiều nhà phát triển không quen thuộc lắm với swift sẽ nói start with like a lot of developers who are not so familiar with swift would say 238 00:19:19,740 --> 00:19:24,440 cái đó let tạo ra các biến bất biến nên bạn không thể thay đổi chúng trong nội bộ that let creates immutable variables so you cannot change them internally 239 00:19:24,440 --> 00:19:30,299 tuy nhiên nếu bạn đang làm việc với let's biến có hằng số let cho however if you're working with a let's variable with a let constant for 240 00:19:30,299 --> 00:19:37,500 ví dụ trong Swift tuy nhiên đó là giá trị bên trong là một thể hiện của một lớp instance in Swift however that that its internal value is an instance of a class 241 00:19:37,500 --> 00:19:42,960 lớp đó có thể biến đổi nội bộ mà không cần biến chữ cái này đang cản trở that class can mutate internally without this letter variable getting in the way 242 00:19:42,960 --> 00:19:47,700 chúng ta hãy xem một ví dụ dành cho những bạn đã quen thuộc với let's have a look at an example for those of you who are familiar with 243 00:19:47,700 --> 00:19:52,080 Mục tiêu C bạn biết rằng có một lớp bên trong Swift Objective C you know that there is a class inside Swift 244 00:19:52,080 --> 00:19:58,080 bây giờ được gọi là mảng có thể thay đổi NS nếu bạn chỉ muốn học Swift còn bạn thì không which is called NS mutable array now if you just want to learn Swift you don't 245 00:19:58,080 --> 00:20:02,400 tất cả đều cần phải biết về điều này đơn giản là dành cho những bạn có một chút at all need to know about this it is simply for those of you who are a little 246 00:20:02,400 --> 00:20:07,140 hơi tò mò về chúng ta và VAR được rồi tôi tôi sẽ chứng minh điều này cho bạn bit curious about let's and VAR okay I'm just going to demonstrate this to you 247 00:20:07,140 --> 00:20:10,559 nhưng làm ơn nếu bạn không hoàn toàn hiểu ví dụ này là but please if you're not completely understanding this example it is 248 00:20:10,559 --> 00:20:14,700 cơ hội hoàn toàn tốt là nếu bạn làm việc với Swift và bạn đang học hỏi completely fine chances are if you're working with Swift and you're learning 249 00:20:14,700 --> 00:20:18,059 Giao diện người dùng Swift Swift và ngay cả khi bạn làm việc với bộ giao diện người dùng chẳng hạn bạn Swift swift UI and even if you're working with UI kit for instance you 250 00:20:18,059 --> 00:20:21,539 tạo ứng dụng giao diện người dùng của bạn cho iOS Mac Hệ điều hành gì cũng được create your UI applications for iOS Mac OS whatever 251 00:20:21,539 --> 00:20:27,780 rất có thể bạn không thực sự sử dụng cái thứ mà tôi sắp cho xem chances are you may not really be using the this uh thing that I'm gonna show 252 00:20:27,780 --> 00:20:33,000 bạn hoặc có thể bạn sẽ sử dụng nó một lần hoặc hai lần trong toàn bộ sự nghiệp của bạn và hơn thế nữa you at all or maybe you'll use it once or twice in your entire career and more 253 00:20:33,000 --> 00:20:37,440 và nhiều hơn nữa Swift ngày càng trở nên hiện đại hơn chúng ta sẽ sử dụng những lớp này nhưng and more Swift gets modern less and less we're going to use these classes so but 254 00:20:37,440 --> 00:20:40,620 dành cho những bạn là Nhà phát triển Mac ví dụ bạn có thể thực sự làm việc for those of you who are Mac Developers for instance you probably actually work 255 00:20:40,620 --> 00:20:45,360 với NS Mutual mảng có lẽ thường xuyên ổn nếu bạn đặc biệt là nếu bạn có một cái cũ with NS Mutual array perhaps often okay if you especially if you have an old 256 00:20:45,360 --> 00:20:49,320 cơ sở mã vì vậy hãy tạo một hằng số ở đây code base so let's create a constant in here where 257 00:20:49,320 --> 00:20:55,500 chúng tôi nói hãy sử dụng mảng cũ và tạo một NS có thể thay đổi mảng ở đây nhé we say let's old array and we create an NS mutable array in here okay 258 00:20:55,500 --> 00:21:01,679 và ở đây chúng ta nói rằng giá trị là một mảng được rồi và sau đó chúng tôi nói and then in here we say that the value is an array okay and then we say the 259 00:21:01,679 --> 00:21:07,380 mảng chứa các giá trị của Foo và bar như thế này được rồi bạn có thể xem ở đây array contains the values of Foo and bar like this okay then you can see in here 260 00:21:07,380 --> 00:21:13,260 sân chơi Swift đó nói mảng cũ là Foo và bar bên phải và bạn thấy ồ đây là that Swift playground says old array as Foo and bar right and you see oh this is 261 00:21:13,260 --> 00:21:18,240 để vậy chúng ta không thể thay đổi nội bộ của nó giá trị bởi vì nếu bạn chẳng hạn có let so we cannot change its internal values because if you for instance have 262 00:21:18,240 --> 00:21:23,100 nhìn lại cái này một mảng nhé được tạo bằng let nếu bạn nói a look at this one an array again okay which is created with let if you say 263 00:21:23,100 --> 00:21:28,260 thêm tên và bạn nói nối thêm và bạn nói xin chào bạn sẽ thấy rằng bạn sẽ nhận được more names and you say append and you say hello you will see that you will get 264 00:21:28,260 --> 00:21:32,940 một lỗi ở đây nó sẽ cho bạn biết rằng bạn không thể thêm vào biến này an error in here it will tell you that you cannot append to this variable 265 00:21:32,940 --> 00:21:37,620 bởi vì nó được tạo bằng let câu lệnh hoặc cú pháp let được rồi trong because it's created with a let statement or a let's syntax okay over in 266 00:21:37,620 --> 00:21:42,780 ở đây vì chúng ta đang tạo một cái cũ mảng bằng với một thể hiện của lớp here since we're creating a let's old array that is equal to a class instance 267 00:21:42,780 --> 00:21:45,960 đó không phải là một cấu trúc và một lần nữa tôi hoàn toàn hiểu rằng chúng tôi chưa which is not a structure and again I completely understand that we haven't 268 00:21:45,960 --> 00:21:50,100 đã nói về các lớp và cấu trúc chưa nhưng chỉ cần biết rằng cái này không phải và cái này talked about classes and structures yet but just know that this is not and this 269 00:21:50,100 --> 00:21:54,720 là cơ bản như tên của nó cho thấy nó là có thể thay đổi nội bộ, nó có thể được thay đổi is basic as its name indicates it is mutable internally it can be changed 270 00:21:54,720 --> 00:21:59,700 cho dù nó được gán cho let hay VAR nó không tạo ra sự khác biệt nào cả, nó là một whether it is assigned to a let or a VAR it doesn't make any difference it is a 271 00:21:59,700 --> 00:22:04,919 lớp trong khi đây là một cấu trúc được rồi và cấu trúc là các loại giá trị và class whereas this is a structure okay and structures are value types and 272 00:22:04,919 --> 00:22:09,780 các lớp là loại tham chiếu được rồi, vì vậy chỉ cần biết rằng bây giờ đây thực sự là classes are reference types okay so just know that for now that this is indeed 273 00:22:09,780 --> 00:22:14,700 có thể thay đổi ngay cả khi nó được gán cho đèn LED có thể thay đổi được rồi đột nhiên bạn mutable even if it is assigned to LED variable okay so now all of a sudden you 274 00:22:14,700 --> 00:22:19,020 có thể nói mảng cũ và sau đó bạn có thể nói thêm và giả sử baz can say old array and then you can say add and let's say baz 275 00:22:19,020 --> 00:22:22,320 được rồi và bây giờ bạn có thể thấy Swift sân chơi chạy mã này và cho bạn biết all right and now you can see Swift playgrounds runs this code and tells you 276 00:22:22,320 --> 00:22:26,580 đó thực sự là bạn hãy không đổi những gì bạn suy nghĩ không đổi đã thay đổi that indeed your let's constant what you thought was constant has changed 277 00:22:26,580 --> 00:22:30,900 bên trong được rồi bây giờ bạn có thể đi phía trước và tạo ra một lời nói mới và chúng tôi nói internally all right now you can go ahead and create a new verbal and we say 278 00:22:30,900 --> 00:22:35,460 mảng mới là mảng cũ và nếu bạn nói mảng mới new array is old array and if you say new array 279 00:22:35,460 --> 00:22:40,200 thêm vào q u x vào đây Cox được rồi và sau đó chúng ta nói add q u x in here Cox okay and then we say 280 00:22:40,200 --> 00:22:45,539 mảng cũ và chúng ta nói mảng mới bây giờ bạn có thể xem kết quả ở đây old array and we say new array now you can see the results in here 281 00:22:45,539 --> 00:22:49,380 vì mảng mới có giá trị cũ mảng since new array got the value of old array 282 00:22:49,380 --> 00:22:54,659 bạn thêm một giá trị mới vào mảng mới này và bạn có thể mong đợi mảng mới you add a new value to this new array and you'd expect probably for new array 283 00:22:54,659 --> 00:22:58,559 chỉ để thay đổi không cho mảng cũ bị ảnh hưởng tuy nhiên bạn có thể thấy kết quả only to change not for old array to be affected however you can see the result 284 00:22:58,559 --> 00:23:03,120 rằng cả mảng cũ và mảng mới đều thực sự đề cập đến điều tương tự that both old array and new array are actually referring to the exact same 285 00:23:03,120 --> 00:23:07,740 mảng nên điều này có thể gây ra nhiều sự nhầm lẫn cho các nhà phát triển dành cho array so this can cause a lot of confusion for developers who are for 286 00:23:07,740 --> 00:23:12,900 ví dụ mới đối với Swift nghĩ rằng ồ tôi vừa tạo một biến bất biến không instance new to Swift thinking that oh I just created a let immutable variable no 287 00:23:12,900 --> 00:23:17,400 người ta có thể thay đổi điều này tuy nhiên bạn có thể thấy rằng nó đã thay đổi và tệ hơn nữa là bạn one can change this however you can see that it got changed and even worse you 288 00:23:17,400 --> 00:23:21,240 có thể như thể bạn chuyển giá trị này cho ví dụ cho một chức năng can as if if you pass this value for instance to a function 289 00:23:21,240 --> 00:23:25,980 và bản thân chức năng đó cũng có thể thay đổi biến này nên khá nguy hiểm and that function itself can also change this variable so it is quite dangerous 290 00:23:25,980 --> 00:23:31,620 chỉ bằng cách sử dụng let không phải là chúng ta hoàn toàn loại bỏ khả năng biến đổi trong just by using let it's not that we're completely getting rid of mutability in 291 00:23:31,620 --> 00:23:36,780 Swift nên rất nhiều thứ có thể sai sót đặc biệt nếu bạn đang sử dụng tài liệu tham khảo Swift so a lot of things can go wrong especially if you're using reference 292 00:23:36,780 --> 00:23:40,679 các loại tham chiếu như mảng nsmutable nhưng đừng lo lắng về điều đó, ý tôi là nếu reference types such as nsmutable array but don't worry about it I mean if if 293 00:23:40,679 --> 00:23:44,820 lúc này nó hơi xa lạ một chút Tôi sẽ giải thích điều này nhiều hơn ở this is a little bit alien at the moment I will explain this a lot more in 294 00:23:44,820 --> 00:23:48,960 chi tiết sau nhé như tôi đã đề cập, hãy hết sức cẩn thận khi details later okay as I mentioned be very careful when 295 00:23:48,960 --> 00:23:53,220 bạn đang làm việc với các loại có thể thay đổi trong Swift và khi bạn vượt qua chúng you're working with mutable types in Swift and when you're passing them for 296 00:23:53,220 --> 00:23:59,100 ví dụ cho các chức năng bởi vì những chức năng thực sự có thể thay đổi instance to functions because those functions can actually change your 297 00:23:59,100 --> 00:24:03,840 loại có thể thay đổi ngay cả khi họ nói họ không ổn vậy chúng ta hãy xem cái này mutable types even if they say they don't okay so let's have a look at this 298 00:24:03,840 --> 00:24:09,179 giả sử chúng ta tạo một mảng khác trong đây hãy sao chép cái này và tôi sẽ bắt đầu let's say we create another array in here let's let's copy this and I'm going 299 00:24:09,179 --> 00:24:16,080 nói vài cái tên rồi chúng ta nói Foo và bar được rồi nên không sao đâu to say let's some names and then we say Foo and bar okay so that's fine let's 300 00:24:16,080 --> 00:24:18,600 tạo ra một chức năng và tôi hoàn toàn hiểu rằng chúng ta chưa nói về create a function and I completely understand we haven't talked about 301 00:24:18,600 --> 00:24:23,039 chưa hoạt động nhưng đây là cú pháp của các chức năng trông như thế nào trong Swift vì vậy chúng tôi functions yet but this is this syntax of what functions look like in Swift so we 302 00:24:23,039 --> 00:24:28,860 nói funk thay đổi mảng và sau đó chúng tôi có một mảng cuộc gọi đối số và ở đây say funk change the array and then we have an argument call array and in here 303 00:24:28,860 --> 00:24:35,340 mình nói mảng NS được rồi bây giờ mình sẽ giải thích cho bạn nsra là gì nsra là ừm và nó là we say NS array okay now I'll explain to you what nsra is nsra is the um and it's 304 00:24:35,340 --> 00:24:41,280 mảng có thể thay đổi là có thể thay đổi biến thể của nsra và nếu bạn thực sự đi mutable array is the mutable variant of nsra and if you actually go 305 00:24:41,280 --> 00:24:45,539 tới mã nguồn cho mảng có thể thay đổi NS giả sử trong mảng Mutual của nó to the source code for NS mutable array let's say in its Mutual array 306 00:24:45,539 --> 00:24:51,539 bạn có thể thấy đó là lớp con nsra nên bất cứ nơi nào bạn có mảng NS Mutual và you can see that it's subclasses nsra so anywhere you have an NS Mutual array and 307 00:24:51,539 --> 00:24:56,159 xin lỗi bất cứ nơi nào chức năng của bạn hoặc cuộc gọi mong đợi và mảng NS bạn thực sự có thể sorry anywhere your function or call expect and NS array you can actually 308 00:24:56,159 --> 00:25:00,240 chuyển một thể hiện của mảng NS Mutual tới bởi vì nó sẽ hoạt động nên nó sẽ hoạt động pass an instance of NS Mutual array to its because it will just work it will be 309 00:25:00,240 --> 00:25:04,559 hạ cấp xuống ns3 nhé vì vậy hãy nói rằng chúng ta nhìn vào cái này downgraded to ns3 okay so let's say that we look at this 310 00:25:04,559 --> 00:25:08,100 chức năng và chức năng này chỉ trông giống như nó đang làm việc với một thứ bất biến function and this function just looks like it is working with an immutable 311 00:25:08,100 --> 00:25:14,520 mảng ở đây tuy nhiên bên trong nó có thể nói rằng hãy nói sao chép dưới dạng mảng array in here however internally it can say let's let's just say copy as array 312 00:25:14,520 --> 00:25:19,679 như trong mảng có thể thay đổi của nó nên đây là một cú pháp trong Swift mà bạn không nên as in its mutable array so this is a syntax in Swift that you shouldn't 313 00:25:19,679 --> 00:25:24,600 thực sự sử dụng nó thường xuyên nhưng mã có thể thực sự làm điều đó mà không cần nhận được really use that often but code can actually do that without without getting 314 00:25:24,600 --> 00:25:29,760 bị Swift nghe lén thực sự ổn nên bạn có thể hãy xem ở đây chúng tôi đang nói rằng chúng tôi đang tạo ra bugged by Swift really okay so you can see in here we're saying we're creating 315 00:25:29,760 --> 00:25:36,419 một bản sao uh ồ một mảng thịnh nộ như thế này nơi chúng ta đang ở a copy uh oh a rage array like this where we're 316 00:25:36,419 --> 00:25:39,360 về cơ bản tạo ra một biến đó là gọi là sao chép tuy nhiên nó không thực sự basically creating a variable that is called copy however it's not really 317 00:25:39,360 --> 00:25:44,039 sao chép phiên bản nó vừa được đặt tên sao chép để có lẽ chúng ta có thể gọi nó là copying the instance it's just named copy so maybe we could just call it 318 00:25:44,039 --> 00:25:49,320 mảng2 hay gì đó hoặc chỉ sao chép nhưng ừ chỉ biết rằng nó thực sự không phải là sao chép array2 or something or just copy but uh just know that it is really not copying 319 00:25:49,320 --> 00:25:55,440 giá trị bên trong cái này hoặc nó chỉ là gán nó cho biến này và nhưng nó the value inside this or it is just assigning it to this variable and but it 320 00:25:55,440 --> 00:26:00,059 đang thiết lập kiểu dữ liệu của nó, nó đang quảng cáo kiểu dữ liệu của nó thành kiểu dữ liệu bất biến is setting its data type it's promoting its data type to immutable data type 321 00:26:00,059 --> 00:26:04,740 nó giả định rằng nó có thể thay đổi được đây thực sự là một đoạn mã tồi mà bạn nên làm it's assuming that it is mutable okay it's this is really bad code you should 322 00:26:04,740 --> 00:26:09,000 không bao giờ viết những thứ như thế này được nhưng tôi chỉ chứng minh rằng nó có thể never write stuff like this okay but I'm just demonstrating that it is possible 323 00:26:09,000 --> 00:26:12,779 để viết mã như thế này và bạn nên loại tự bảo vệ mình khỏi mã như to write code like this and you should kind of guard yourself against code like 324 00:26:12,779 --> 00:26:19,440 cái này và ở đây chúng ta nói sao chép dấu chấm thêm Thánh lễ được rồi nếu bạn vượt qua nếu bạn this and then in here we say copy dot add Mass okay now if you pass if you 325 00:26:19,440 --> 00:26:23,880 gọi hàm này thay đổi mảng bằng Mảng tương hỗ của bạn mọi thứ sẽ chỉ call this function change the array with your Mutual array everything will just 326 00:26:23,880 --> 00:26:28,860 hoạt động như mong đợi một số tên và sau đó bạn có thể nói một số tên và có work as expected some names and then you can say some names and have 327 00:26:28,860 --> 00:26:33,179 nhìn vào dữ liệu bây giờ khi mã này được chạy bạn có thể thấy trong a look at the data now when this code is run you can see in 328 00:26:33,179 --> 00:26:38,400 phạm vi này một số tên sau khi được thông qua để thay đổi mảng thực sự đã được this scope some names after being passed to change the array has actually been 329 00:26:38,400 --> 00:26:43,740 bị đột biến bên trong, bạn có thể thấy thanh Foo và vượt qua để vượt qua chức năng này internally mutated you can see Foo bar and pass so this pass that this function 330 00:26:43,740 --> 00:26:48,179 được thêm vào mảng này thực sự có mặt bên ngoài chức năng đó cũng đơn giản added to this array is actually present outside that function as well simply 331 00:26:48,179 --> 00:26:51,120 bởi vì chúng tôi đang làm việc lại với các loại tham chiếu có nghĩa là có một because we're working again with reference types meaning that there's one 332 00:26:51,120 --> 00:26:54,480 bản sao của cái này trong bộ nhớ và cái này chức năng thực sự đang thay đổi copy of this in the memory and this function is actually changing the 333 00:26:54,480 --> 00:27:00,120 bản gốc nhé vậy đó thực sự là ừ đó là điều tôi original copy okay so that was really uh it that's what I 334 00:27:00,120 --> 00:27:05,100 muốn giải thích cụ thể về điều này phần của video có các biến và wanted to explain in this particular section of the video with variables and 335 00:27:05,100 --> 00:27:12,120 ừ hằng số nên chỉ cần biết rằng bạn có hãy để và bạn có VAR và hãy để nó nếu uh constants so just know that you have let and you have VAR and let it if 336 00:27:12,120 --> 00:27:17,580 làm việc với các loại giá trị như cấu trúc của mảng hoặc chuỗi Swift hoặc working with value types such as structures of Swift arrays or strings or 337 00:27:17,580 --> 00:27:24,360 số nguyên nó ngăn cản sự bất biến của giá trị đó bên trong có nghĩa là bạn integers it prevents immutability of that value internally meaning that you 338 00:27:24,360 --> 00:27:29,960 không thể thay đổi van dot này thành for ví dụ nói và tên tôi tên tôi can't change this van dot to for instance say and my name my name 339 00:27:29,960 --> 00:27:36,179 ừ và sau đó bạn có thể nói thực sự bằng với tên của tôi uh and then you can say is equal to actually my name make 340 00:27:36,179 --> 00:27:40,860 viết hoa bạn không thể làm những việc như thế này vì vậy bạn không thể và muốn thay đổi giá trị uppercase you can't do stuff like this so you cannot and like change the value 341 00:27:40,860 --> 00:27:47,279 được gán cho cái này và bạn không thể gán lại giá trị cho tên của tôi sau khi nó có that is assigned to this and you can't reassign a value to my name after it has 342 00:27:47,279 --> 00:27:52,740 đã được tạo ra rồi nên việc phân công lại rằng bạn không thể gán lại giá trị cho một been created okay so the reassigning that you cannot reassign a value to a 343 00:27:52,740 --> 00:27:58,440 để hằng số áp dụng cho cả hai tham chiếu loại và loại giá trị nên nó không let constant applies to both reference types and and value type so it doesn't 344 00:27:58,440 --> 00:28:04,140 vấn đề nếu giá trị bên trong này cho phép hằng số là một chuỗi hoặc nó là một thể hiện matter if if the value inside this let constant is a string or it's an instance 345 00:28:04,140 --> 00:28:09,059 của một lớp miễn là nó cho phép bạn không thể gán một giá trị mới cho nó chẳng hạn of a class as long as it's let you can't assign a new value to it for instance 346 00:28:09,059 --> 00:28:14,760 giả sử đây là bạn có thể thấy nó là một tổng tên nó là một thể hiện của một lớp let's say here is you can see it is a sum names it is an instance of a class 347 00:28:14,760 --> 00:28:20,220 đó là một loại tham chiếu Tuy nhiên thực tế là bạn không thể gán lại giá trị cho which is a reference type However the fact that you cannot reassign a value to 348 00:28:20,220 --> 00:28:25,380 điều này vẫn đúng cho dù đó là giữ một thể hiện của một lớp hoặc một this still holds true whether it is holding an instance of a class or an 349 00:28:25,380 --> 00:28:31,440 ví dụ của một cấu trúc vì vậy hãy nói một số cái tên thật vớ vẩn ở đây bây giờ chúng ta nên instance of a structure so let's say some names is blah in here now we should 350 00:28:31,440 --> 00:28:36,720 gặp lỗi ở đây khi nói rằng bạn không thể gán lại giá trị khác cho giá trị này get an error in here saying that you cannot reassign another value to this 351 00:28:36,720 --> 00:28:42,240 sau khi bạn đã tạo nó thì thế này việc gán lại cho hằng số let được áp dụng after you have created it so this reassigning to a let constant applies 352 00:28:42,240 --> 00:28:49,260 cả loại tham chiếu và loại giá trị tuy nhiên khả năng biến đổi bên trong của một both to reference types and value types however the internal mutability of a 353 00:28:49,260 --> 00:28:56,279 hằng số hãy chỉ áp dụng ngăn chặn sự biến đổi nội bộ của một let's constant only applies the prevention of internal mutability of a 354 00:28:56,279 --> 00:29:01,500 hằng số chỉ áp dụng cho các loại Giá trị chẳng hạn như cấu trúc nếu bạn đã chỉ định một let constant only applies to Value types such as structures if you've assigned a 355 00:29:01,500 --> 00:29:06,539 lớp thành hằng số let lớp có thể thay đổi nội bộ mà không có Swift thực sự class to a let constant the class might internally change without Swift actually 356 00:29:06,539 --> 00:29:11,340 phàn nàn chút nào cũng được nên tôi hoàn toàn hiểu là hơi phức tạp một chút complaining at all okay so I completely understand is a little bit complicated 357 00:29:11,340 --> 00:29:15,120 và cá nhân tôi tin rằng một số khác ngôn ngữ cá nhân đã thực hiện điều này and I personally believe that some other personal languages have implemented this 358 00:29:15,120 --> 00:29:20,340 đẹp hơn một chút và giống chất lỏng hơn như rỉ sét a little bit more beautifully and a little more like fluid such as rust 359 00:29:20,340 --> 00:29:24,480 tôi thực sự có thể có một số khóa học về cũng rỉ sét nên bạn có thể xem Ross của tôi can I have some courses actually about rust as well so you can watch my Ross 360 00:29:24,480 --> 00:29:28,380 ví dụ như khóa học cấp tốc trên YouTube và tìm hiểu về khả năng biến đổi và rỉ sét crash course for instance on YouTube and learn about mutability and rust as well 361 00:29:28,380 --> 00:29:33,000 nhưng tôi tin rằng Russ có thực hiện có thể thay đổi tốt hơn một chút so với but I I believe that Russ has implemented mutably a bit nicer than 362 00:29:33,000 --> 00:29:38,279 Swift và vì Swift có thể gây ra một số nhầm lẫn trong cách xử lý và có thể thay đổi Swift and because Swift can cause some confusion in how it handles and mutable 363 00:29:38,279 --> 00:29:43,380 giá trị nhưng bây giờ chỉ cần biết những điều này các quy tắc đơn giản và sau đó chúng ta có thể chuyển sang values but for now just know these simple rules and then we can move on to 364 00:29:43,380 --> 00:29:48,299 phần tiếp theo của video này được rồi bây giờ chúng ta đã nói chuyện đủ rồi the next section of this video all right now that we've talked enough 365 00:29:48,299 --> 00:29:53,100 về các biến hãy chuyển sang biến khác khái niệm rất rất quan trọng đối với about variables let's move on to another concept which is very very important to 366 00:29:53,100 --> 00:29:56,460 học bằng bất kỳ ngôn ngữ lập trình nào hiện tại bạn đang học và những điều đó learn in any programming language that you're learning at the moment and those 367 00:29:56,460 --> 00:30:02,700 là hoặc đó là toán tử nên toán tử là những hàm nhỏ có một chút are or that is operators so operators are small functions that are a little 368 00:30:02,700 --> 00:30:08,940 hơi đặc biệt trong cách chúng được khai báo và Swift đối xử với họ như vậy nó đối xử với họ bit special in how they're declared and Swift treats them as such it treats them 369 00:30:08,940 --> 00:30:12,539 đặc biệt hơn một chút so với những người khác hoạt động như vậy và chúng ta hãy xem xét a little bit more special than other functions so and let's have a look at 370 00:30:12,539 --> 00:30:16,500 toán tử là gì nhưng trước khi làm điều đó hãy tạo một sân chơi đơn giản cho what operators are but before doing that let's create a simple playground for 371 00:30:16,500 --> 00:30:21,899 các toán tử vì vậy hãy nói đi hãy nói tập tin mới và chúng tôi nói tập tin nếu chúng tôi có thể tìm thấy nó operators so let's say go let's say file new and we say file if we can find it oh 372 00:30:21,899 --> 00:30:26,220 chúng tôi không thể vì chúng tôi không thể tạo một tập tin bên trong cái này vậy chúng ta hãy vào đây bên trong we can't because we can't create a file inside this so let's be in here inside 373 00:30:26,220 --> 00:30:30,600 biên tập viên của chúng tôi và tôi sẽ nói lệnh n và sau đó tôi sẽ tiếp tục và our editor and I'm going to say command n and then I'm going to go ahead and 374 00:30:30,600 --> 00:30:35,100 tạo một sân chơi ở đây giả sử sân chơi trống và sau đó chúng ta sẽ đến create a playground in here let's say blank playground and then we're going to 375 00:30:35,100 --> 00:30:40,080 nói các nhà điều hành nhưng hãy hết sức cẩn thận bởi vì theo mặc định nên nếu sân chơi hoặc say operators but be very careful because by default so if playgrounds or 376 00:30:40,080 --> 00:30:44,220 xcode thực sự cố gắng tạo ra cái này sân chơi bên trong một sân chơi khác và xcode actually tries to create this playground inside another playground and 377 00:30:44,220 --> 00:30:50,640 điều đó thật kinh khủng, nó thực sự đã đầy và xin vui lòng chỉ sử dụng thư mục chính that is horrible it is really off full and just please just use the main folder 378 00:30:50,640 --> 00:30:54,659 để tạo sân chơi của bạn và cũng có thể thêm nó vào phần chính to create your playground and also add it to the main 379 00:30:54,659 --> 00:30:59,760 cấu trúc không gian làm việc xcode cũng như trong ở đây vì vậy hãy nói tạo xcode workspace structure as well in here so let's say create 380 00:30:59,760 --> 00:31:03,000 bây giờ chúng ta có các toán tử và hãy thực hiện điều tương tự ở đây tôi muốn nói nhập khẩu now we have operators and let's do the same thing in here I want to say import 381 00:31:03,000 --> 00:31:07,440 Nền tảng ổn sau khi làm xong việc này chúng ta hãy bắt đầu nói chuyện Foundation okay after doing this let's start talking 382 00:31:07,440 --> 00:31:11,700 Về toán tử vì vậy hãy tạo hai hằng số about operators so let's create two constants 383 00:31:11,700 --> 00:31:17,100 ở đây hãy nói tuổi của tôi và chúng tôi nói 22 và chúng tôi nói hãy để tuổi của bạn là 20 được không in here let's say my age and we say 22 and we say let your age is 20 okay 384 00:31:17,100 --> 00:31:22,080 bây giờ hãy làm việc với hai cái đầu tiên của chúng ta các toán tử và những cái đó lớn hơn now let's work with our first two operators and those are the greater than 385 00:31:22,080 --> 00:31:26,880 và ít hơn toán tử nếu bạn có hai những số nguyên như thế này và tôi khá mong đợi and less than operators if you have two integers like this and I kind of expect 386 00:31:26,880 --> 00:31:30,240 bạn đã biết số nguyên là gì từ ngôn ngữ chương trình khác có lẽ đó you to already know what an integer is from other program language perhaps that 387 00:31:30,240 --> 00:31:35,940 bạn đã biết rồi thì chúng ta sẽ nói nếu tuổi của tôi sau đó khi bạn có hai số nguyên bạn có thể you already know then we say if my age then once you have two integers you can 388 00:31:35,940 --> 00:31:40,260 sử dụng toán tử cụ thể này mà bạn có thể thấy nó nói lớn hơn bên trái use this particular operator that you can see it says greater than so the left 389 00:31:40,260 --> 00:31:46,559 bên phải lớn hơn bên phải bên tuổi của bạn và tuổi của bạn và đây là side should be greater than the right side your age and your age and this is 390 00:31:46,559 --> 00:31:51,960 một câu lệnh if được thôi, tôi nghĩ vậy thực ra tôi đã mong đợi bạn an if statement okay which I kind of already actually I kind of expect you to 391 00:31:51,960 --> 00:31:56,760 đã biết câu lệnh if là như vậy rồi bạn có thể thấy bây giờ chúng tôi đang sử dụng if already know what if statements are so you can see now we're using an if 392 00:31:56,760 --> 00:32:01,260 tuyên bố và sau đó và đặt bên trái của chúng tôi biến bên tay phải và bên tay phải statement and then and putting our left hand side and right hand side variables 393 00:32:01,260 --> 00:32:06,840 ở đây và sử dụng toán tử đó là có loại cú pháp này vậy thì sao in here and using operator which is having this kind of a syntax so what 394 00:32:06,840 --> 00:32:10,919 toán tử này đang làm là so sánh giá trị ở bên trái với giá trị ở this operator is doing is comparing the value to the left with the value to the 395 00:32:10,919 --> 00:32:15,299 right và nó Trả về giá trị true nếu giá trị bên trái thực sự là right and it Returns the value of true if the value to the left is indeed 396 00:32:15,299 --> 00:32:20,880 lớn hơn giá trị bên phải nhé và ở đây chúng ta có thể nói tôi già hơn greater than the value to the right okay and here then we can say I'm older than 397 00:32:20,880 --> 00:32:27,899 bạn ổn và sau đó chúng ta sẽ nói khác nếu H của tôi là nhỏ hơn H của bạn nên đây là cái khác you okay and then we say else if my H is less than your H so this is another 398 00:32:27,899 --> 00:32:32,460 toán tử hoạt động giữa các số nguyên cho ví dụ nói rằng tôi sẽ quay lại operator that works between integers for instance that says it will I will return 399 00:32:32,460 --> 00:32:37,200 đúng nếu giá trị bên trái nhỏ hơn hơn giá trị bên phải thì ở đây true if the value to the left is less than the value to the right then in here 400 00:32:37,200 --> 00:32:45,840 chúng tôi nói tôi trẻ hơn bạn và ồ này chúng ta bằng tuổi nhau được thôi vậy nếu tôi we say I'm younger than you and else oh hey we are the same age okay so if I'm 401 00:32:45,840 --> 00:32:49,860 không già hơn bạn và tôi không trẻ hơn hơn bạn thì chúng ta phải bằng tuổi nhau not older than you and I'm not younger than you then we should be the same age 402 00:32:49,860 --> 00:32:53,220 về mặt logic, được rồi, bạn không thể thấy gì cả đang diễn ra ở sân chơi này bởi vì logically all right you can see nothing is happening in this playground because 403 00:32:53,220 --> 00:32:56,820 chúng tôi không có chế độ chạy tự động nên tôi tôi sẽ giữ trackpad của tôi trên cái này we don't have automatic running so I'm just gonna hold my trackpad on this 404 00:32:56,820 --> 00:33:00,299 nút và sau đó tôi sẽ nói tự động chạy và sau đó bạn có thể thấy button and then I'm gonna say automatically run and then you can see 405 00:33:00,299 --> 00:33:05,100 mã của chúng ta sẽ chạy ở đây và giá trị cơ bản mà chúng tôi có được that our code is going to run in here and the value basically we got into this 406 00:33:05,100 --> 00:33:08,760 nhánh của câu lệnh if của chúng tôi Tôi già hơn hơn bạn đơn giản vì toán tử này branch of our if statement I'm older than you simply because this operator 407 00:33:08,760 --> 00:33:14,100 đã chỉ ra cho Swift rằng giá trị của trái thực sự là lớn hơn giá trị indicated to Swift that the value to the left is indeed uh larger than the value 408 00:33:14,100 --> 00:33:19,200 ở bên phải trả về giá trị true và sau đó Swift rơi vào trường hợp này nếu to the right return the value of true and then Swift fell into this if 409 00:33:19,200 --> 00:33:24,299 tuyên bố vì vậy đó là hai toán tử đầu tiên mà chúng tôi thấy trong statement so that's these two are the first operators that we're seeing in 410 00:33:24,299 --> 00:33:28,380 Swift về cơ bản tuy nhiên ý tôi là có một số toán tử rất đặc biệt khác như Swift basically however I mean there are some other very special operators such 411 00:33:28,380 --> 00:33:32,340 là toán tử tương đương mà chúng ta đang thấy ở đây nhưng chúng ta thực sự không nên tiếp tục as the equal operator that we're seeing in here but we shouldn't really go ahead 412 00:33:32,340 --> 00:33:36,419 và giải thích rằng chúng tôi chỉ đơn giản là gán giá trị cho một biến ở đây and explaining that we're simply assigning a value to a variable in here 413 00:33:36,419 --> 00:33:40,799 với nhà điều hành đó được rồi bây giờ có các toán tử khác như with that operator okay now there are other operators such as 414 00:33:40,799 --> 00:33:46,980 Ngoài ra, ví dụ hãy nói hãy để tôi tuổi mẹ bằng tuổi con cộng 30. vậy đây Plus for instance let's say let my mother's age is my age plus 30. so this 415 00:33:46,980 --> 00:33:51,480 là một nhà điều hành đang vận hành giữa hai số nguyên tôi có thể từ bên trái is a an operator that is operating between two integers I can from the left 416 00:33:51,480 --> 00:33:54,179 bên tay và một bên tay phải vì vậy nó chỉ đơn giản là mất hand side and a right hand side so it simply takes 417 00:33:54,179 --> 00:33:59,100 giá trị ở bên trái và thêm giá trị ở bên phải nó và sau đó trả về the value to the left and adds the value to the right to it and then returns that 418 00:33:59,100 --> 00:34:04,080 kết quả cho chúng tôi được rồi vậy đó là một toán tử khác mà chúng tôi đang result to us okay so that's another operator that we're 419 00:34:04,080 --> 00:34:09,300 nhìn thấy ở đây toán tử cộng bạn có thể tất nhiên cũng sử dụng ví dụ seeing in here the plus operator you can also of course use for instance the 420 00:34:09,300 --> 00:34:12,899 toán tử nhân và chúng ta có thể nói hãy nhân đôi multiplication operator and we can say let's double 421 00:34:12,899 --> 00:34:19,560 và gấp đôi tuổi của tôi là H của tôi và bạn nói nhân hai và như bạn có thể thấy đây là một and double my age is my H and you say times two and as you can see this is an 422 00:34:19,560 --> 00:34:22,859 người điều hành đang ngồi giữa hai số nguyên một lần nữa nó lấy số nguyên để operator that is sitting between two integers again it takes the integer to 423 00:34:22,859 --> 00:34:27,119 bên trái và nhân nó với số nguyên ở bên phải và trả về the left and and multiplies it by the integer to the right and Returns the 424 00:34:27,119 --> 00:34:32,639 giá trị và sau đó được gán cho biến này bạn có thể thấy nó là 44. nếu value and which then gets assigned to this variable you can see it's 44. if 425 00:34:32,639 --> 00:34:37,740 bạn có nhớ tuổi được đặt là 22 lần không 2 là 44. you remember the age was set to 22 times 2 is 44. 426 00:34:37,740 --> 00:34:42,240 vậy có lẽ bây giờ bạn đã thấy một vài người vận hành ở đây và bạn đang tự hỏi so you've probably now seen a few operators in here and you're wondering 427 00:34:42,240 --> 00:34:46,800 được rồi có bao nhiêu loại khác nhau các nhà khai thác ở đó và có ba okay how many different types of operators are there and there are three 428 00:34:46,800 --> 00:34:53,159 các loại toán tử khác nhau trong Swift và ý tôi là không, tôi không tính những thứ này different types of operators in Swift and I mean not I'm not counting these 429 00:34:53,159 --> 00:34:58,140 các toán tử tôi đang nói về ba các loại toán tử khác nhau được operators I'm just talking about three different types of operators okay 430 00:34:58,140 --> 00:35:05,580 cái đầu tiên được gọi là tiền tố đơn nhất cái thứ hai được gọi là hậu tố đơn nhất the first one is called a unary prefix the second one is called a unary postfix 431 00:35:05,580 --> 00:35:11,460 và cái thứ ba được gọi là nhị phân sửa lỗi được rồi nên khi chúng ta nói về and the third one is called a binary infix okay so when we're talking about 432 00:35:11,460 --> 00:35:16,380 đơn nhất như bạn nhớ hãy thực sự viết chúng ra hãy chỉ nói ừ một là unary as you remember let's actually write them down let's just say uh one is 433 00:35:16,380 --> 00:35:24,720 tiền tố tiết niệu đơn nhất thứ hai là hậu tố tiết niệu và sau đó là hậu tố thứ ba unary urinary prefix the second one is urinary postfix and then the third one 434 00:35:24,720 --> 00:35:29,640 trung tố nhị phân có được không bất cứ nơi nào bạn nhìn thấy đơn nguyên chỉ cần biết is binary infix okay wherever you're seeing unary just know 435 00:35:29,640 --> 00:35:34,320 rằng thứ này chỉ hoạt động với một giá trị lại hoạt động với một giá trị và that this thing is working with only one value again working with one value and 436 00:35:34,320 --> 00:35:38,640 nhị phân đang hoạt động với hai giá trị được vì vậy bây giờ bạn có thể tưởng tượng rằng đây binary is working with two values okay so you can now imagine that this 437 00:35:38,640 --> 00:35:42,180 toán tử toán tử nhân đang làm việc với hai giá trị là operator the multiplication operator that is working with two values is 438 00:35:42,180 --> 00:35:47,400 thực sự là một hệ nhị phân đã được sửa chữa, nó là hệ nhị phân bởi vì nó hoạt động với hai giá trị indeed a binary in fix it is binary because it's working with two values the 439 00:35:47,400 --> 00:35:51,900 bên trái và bên phải và nó là một toán tử infix vì nó đang ngồi left and the right hand side and it is an infix operator because it's sitting 440 00:35:51,900 --> 00:35:58,200 ở giữa nên infix ở giữa được rồi ngồi ở giữa hai giá trị khác nên in between so infix in between okay it's sitting in between two other values so 441 00:35:58,200 --> 00:36:03,440 tất cả các toán tử mà chúng ta đã thấy cho đến nay lớn hơn hoặc ít hơn all the operators that we've seen so far the greater than or less than 442 00:36:03,440 --> 00:36:08,760 về cơ bản phép cộng và bội phép nhân là trung tố nhị phân basically addition and multiple multiplication are binary infix 443 00:36:08,760 --> 00:36:14,460 các toán tử chúng ta chưa từng thấy một ngôi và Sr tiền tố đơn nhất và hậu tố đơn nhất operators we haven't seen a unary and Sr unary prefix and unitary postfix so 444 00:36:14,460 --> 00:36:20,040 chúng ta hãy xem tiền tố đơn nhất như bạn mong đợi đơn nguyên chỉ hoạt động với một let's have a look at unary prefix as you'd expect unary Works only with one 445 00:36:20,040 --> 00:36:25,980 giá trị vì vậy hãy giả sử Foo là đúng vậy đây chỉ là gán giá trị true value so let's say let's Foo is true so this is just assigning the value of true 446 00:36:25,980 --> 00:36:30,660 Tuy nhiên, thành Foo nếu bạn muốn thay đổi giá trị này đúng thành sai và bạn muốn to Foo however if you want to change the value of this true to false and you want 447 00:36:30,660 --> 00:36:35,940 để lật nó về cơ bản bạn sử dụng cái này toán tử ở đây là dấu nháy đơn to flip it basically you use this operator in here which is the apostrophe 448 00:36:35,940 --> 00:36:41,280 toán tử là tiền tố đơn nhất toán tử lấy giá trị về nó operator which is a unary prefix operator that takes the value to its 449 00:36:41,280 --> 00:36:46,200 phía bên tay phải và về cơ bản ừm phủ nhận điều đó được rồi nên bạn có thể nhìn thấy trong right hand side and basically um negates it okay so you can see in 450 00:36:46,200 --> 00:36:51,119 ở đây đúng trở thành sai đơn giản như thế vì vậy đây là tiền tố đơn nhất, nó là tiền tố here true became false simply like that so this is a unary prefix it's prefix 451 00:36:51,119 --> 00:36:56,640 bởi vì nó ở trước giá trị xuất hiện ngay sau đó được rồi because it's before the value that comes right after it okay 452 00:36:56,640 --> 00:37:02,160 sau đó chúng tôi có một bài sửa chữa bài tiết niệu vì vậy đề nghị postfix đơn nhất là một chút then we have a urinary post fix so a unary postfix offer is a little bit 453 00:37:02,160 --> 00:37:05,579 ý tôi là đặc biệt trong tất cả những năm tôi làm việc làm việc với swift tôi đang làm việc special I mean in all my years of working with swift I've been working 454 00:37:05,579 --> 00:37:12,300 với swift kể từ mùa hè năm 2014. đó là rất rất hiếm khi bạn tạo ra with swift since summer of 2014. it is very very seldom that you create your 455 00:37:12,300 --> 00:37:16,380 toán tử sửa lỗi sau của riêng bạn và bạn muốn đọc postfix Có một số thống nhất own post-fix operator and you want to read postfix There are some unitary 456 00:37:16,380 --> 00:37:21,119 toán tử postfix đã được xây dựng rồi vào Swift nhưng có lẽ bạn sử dụng chúng postfix operators already it's built into Swift but and you use them perhaps 457 00:37:21,119 --> 00:37:26,579 khá nhiều tuy nhiên việc tạo của riêng bạn postfix uh toán tử postex đơn nhất là quite a lot however creating your own postfix uh unary postsex operator is 458 00:37:26,579 --> 00:37:30,540 điều gì đó bạn làm rất rất hiếm khi được rồi something that you do very very seldom okay 459 00:37:30,540 --> 00:37:34,440 chúng ta hãy nhìn vào một hậu tố đơn nhất nhà điều hành hãy nói tên let's have a look at a unary postfix operator let's say name 460 00:37:34,440 --> 00:37:38,940 và tôi sẽ tạo một tùy chọn giá trị bây giờ tôi biết chúng ta chưa nói về and I'm just going to create an optional value now I know we haven't talked about 461 00:37:38,940 --> 00:37:43,140 tùy chọn nhưng chỉ nhằm mục đích chứng minh một hậu tố đơn nhất là gì optionals but just for the purpose of demonstrating what a unary postfix 462 00:37:43,140 --> 00:37:47,220 toán tử là hãy tiếp tục và viết cú pháp này giả sử là tùy chọn và sau đó operator is let's go ahead and write this syntax let's say optional and then 463 00:37:47,220 --> 00:37:51,839 chúng tôi nói kết xuất ổn bây giờ nếu bạn muốn lấy giá trị đó we say rendered okay now if you want to grab the value that 464 00:37:51,839 --> 00:37:57,740 nằm bên trong biến này và chúng ta mở nó ra nói hãy đơn nhất is inside this variable and unwrap it we say let unary 465 00:37:57,740 --> 00:38:04,619 postfix bằng tên và sau đó chúng tôi đặt dấu nháy đơn này sau tên này bây giờ chỉ postfix is equal to name and then we put this apostrophe after this name now just 466 00:38:04,619 --> 00:38:09,000 bây giờ biết rằng những gì chúng ta đã làm ở đây là chúng tôi đặt một giá trị tùy chọn know for now that what the what we did in here is that we put an optional value 467 00:38:09,000 --> 00:38:13,619 thành một tên gọi biến tùy chọn đơn giản có nghĩa là tên này có thể into a variable call name an optional simply means that this name can either 468 00:38:13,619 --> 00:38:17,640 chứa các giá trị null hoặc nó có thể chứa một giá trị đó là tùy chọn trong Swift contain null values or it can contain a value that's what optionality in Swift 469 00:38:17,640 --> 00:38:22,200 có nghĩa là nhưng tôi đã chuẩn bị đầy đủ sân chơi riêng cho các lựa chọn means but I've prepared a completely separate playground for optionals which 470 00:38:22,200 --> 00:38:26,700 chúng ta sẽ nói về một chút tuy nhiên sau này bạn có thể thấy bây giờ nó we're going to talk about a little bit later however this you can see now it 471 00:38:26,700 --> 00:38:31,800 tiếp tục với giá trị tùy chọn này và lấy giá trị nội bộ và gán nó goes ahead into this optional value and grabs the internal value and assigns it 472 00:38:31,800 --> 00:38:38,700 với điều này được rồi vì vậy hãy nói nếu chúng ta kế thừa nói loại tên và sau đó chúng ta có thể gõ to this okay so let's say if we inherit say type of name and then we can type of 473 00:38:38,700 --> 00:38:43,800 hậu tố đơn nhất bây giờ họ có hai các loại khác nhau bạn có thể thấy loại unary postfix now they have two different types you can see the type of 474 00:38:43,800 --> 00:38:48,420 biến này là một chuỗi tùy chọn và loại biến này thực sự là một this variable is an optional string and the type of this variable is indeed a 475 00:38:48,420 --> 00:38:55,020 chuỗi nên toán tử hậu tố đơn nhất này đi vào bên trong tùy chọn này và lấy string so this unary postfix operator went inside this optional and grabbed 476 00:38:55,020 --> 00:39:00,000 giá trị của nó ra và buộc nó ra và gán nó cho biến bên trái its value out and forced it out and assign it to the variable to the left 477 00:39:00,000 --> 00:39:03,540 về cơ bản là sử dụng phép gán toán tử gán hand side basically using the assign assignments operator 478 00:39:03,540 --> 00:39:09,839 vì vậy đây là toán tử hậu tố đơn nhất xuất hiện sau một biến và nó chỉ hoạt động so this is a unary postfix operator it comes after a variable and it works only 479 00:39:09,839 --> 00:39:15,300 với một biến nên nó không có biến ở đây và biến ở đó with one variable so it doesn't have a variable here and a variable there it is 480 00:39:15,300 --> 00:39:18,800 chỉ làm việc với Val và biến về phía bên trái của nó nhé only working with the Val and the variable to its left hand side okay 481 00:39:18,800 --> 00:39:25,260 tiền tố tiền tố đơn nhất hoạt động với giá trị sau khi nó đăng hoặc postfix hoạt động với prefix unary prefix works with the value after it post or postfix works with the 482 00:39:25,260 --> 00:39:30,839 giá trị trước khi nó ổn vì vậy đó là ví dụ thứ hai về cơ bản cho đơn nguyên value before it okay so that's the second example basically for unary 483 00:39:30,839 --> 00:39:36,000 hậu tố bây giờ là loại toán tử cuối cùng postfix now for the last type of operator which 484 00:39:36,000 --> 00:39:40,380 là loại phổ biến nhất và chúng tôi gọi chúng là trung tố nhị phân đơn giản chỉ vì chúng hoạt động is the most common type and we call them binary infix simply because they work 485 00:39:40,380 --> 00:39:45,900 với hai giá trị do đó tên nhị phân và cũng infix đơn giản chỉ vì họ ngồi with two values hence the name binary and also infix simply because they sit 486 00:39:45,900 --> 00:39:52,020 ở giữa các giá trị mà họ làm việc trên được rồi, giả sử kết quả là một cộng in between the values that they work on okay so let's say a result is one plus 487 00:39:52,020 --> 00:39:57,960 hai và đây là một ví dụ đơn giản về toán tử trung tố nhị phân bạn có thể thấy nó two and this is a simple example of a binary infix operator you can see it's 488 00:39:57,960 --> 00:40:01,260 làm việc với hai giá trị và ngồi trong giữa họ được chứ working with two values and sits in between them okay 489 00:40:01,260 --> 00:40:06,000 và một ví dụ khác là giả sử hãy để tên bằng Foo and other another example is let's say let names is equal to Foo 490 00:40:06,000 --> 00:40:11,520 và sau đó chúng ta nói cộng không gian trống cộng thanh và đây là một cái khác and then we say plus empty space plus bar and this is another 491 00:40:11,520 --> 00:40:14,460 ừm trung tố nhị phân um infix binary 492 00:40:14,460 --> 00:40:18,780 người điều hành đang ngồi giữa hai những sợi dây bạn có thể thấy bạn có thể hơi nhỏ operator that is sitting between two strings you can see you may be a little 493 00:40:18,780 --> 00:40:23,400 hơi khó hiểu bạn có thể nói ồ nhưng nếu điều này đang ngồi giữa hai sợi dây này bit confusing you can say oh but if this is sitting between these two strings 494 00:40:23,400 --> 00:40:28,859 cái gì ở giữa này có phải là cái gì không toán tử tiền tố à, nó không phải là cái gì what is this sitting in between is it a prefix operator well it is not what is 495 00:40:28,859 --> 00:40:32,040 xảy ra ở đây là Swift là thực thi mã này từ tay trái happening here is that Swift is executing this code from the left hand 496 00:40:32,040 --> 00:40:37,619 bên vì không có dấu ngoặc đơn sau đó nó báo được rồi Foo cộng với khoảng trống side because there is no parenthesis then it says okay Foo plus empty space 497 00:40:37,619 --> 00:40:43,859 trở thành Foo cộng như không gian trống rỗng như cái này rồi lấy cái này cộng và sử dụng becomes Foo plus like empty space like this and then takes this plus and uses 498 00:40:43,859 --> 00:40:47,700 nó ở giữa kết quả của lần trước tuyên bố và Bar it in between the result of the previous statement and Bar 499 00:40:47,700 --> 00:40:52,079 được rồi đó là những gì đang xảy ra bên trong mã này về cơ bản okay so that's what is happening inside this code basically 500 00:40:52,079 --> 00:40:56,640 được rồi, đó là một ví dụ về hệ nhị phân toán tử infix và như tôi đã đề cập nhiều nhất okay so that was an example of a binary infix operator and as I mentioned most 501 00:40:56,640 --> 00:41:00,540 các toán tử bạn sử dụng trong Swift là sẽ là nhị phân và sửa lỗi operators that you use in Swift are going to be binary and fix there are 502 00:41:00,540 --> 00:41:04,740 thực tế là khá nhiều nhà khai thác khác cũng vậy nhưng chúng tôi không sử dụng chúng thường xuyên quite a lot of actually other operators as well but we don't use them so often 503 00:41:04,740 --> 00:41:08,460 được rồi cũng phụ thuộc vào mã của bạn căn cứ okay depends again also on your code base 504 00:41:08,460 --> 00:41:14,339 bây giờ có một thể loại khác toán tử và được gọi là ternary now there is another category of operators and which is called a ternary 505 00:41:14,339 --> 00:41:19,200 toán tử được rồi và ternary là một cái gì đó đó là một loại Chủ đề Nóng trong bất kỳ operator okay and ternary is something that is a kind of a Hot Topic in any 506 00:41:19,200 --> 00:41:23,339 ngôn ngữ lập trình hỗ trợ ternary đơn giản vì nó có thể bị lạm dụng programming language that supports ternary simply because it can be misused 507 00:41:23,339 --> 00:41:29,880 và nó có thể khiến mã của bạn trông rất thực sự rất khó đọc vì vậy and it can cause your code to look very very difficult to read actually so 508 00:41:29,880 --> 00:41:36,480 ừ những gì tôi đề nghị ôi những gì tôi nghĩ là ý tưởng hay là luôn kiểm tra với uh của bạn um what I suggest oops what I think is a good idea is always a check with your uh 509 00:41:36,480 --> 00:41:41,400 với các đồng đội của bạn đang làm việc cùng đồng nghiệp của bạn về cơ bản là trong nhóm của bạn with your teammates who are working with your colleagues basically in your team 510 00:41:41,400 --> 00:41:46,140 và hỏi xem họ có thấy thoải mái không với ternary và nếu có and ask them if if they're comfortable with ternary and if they're if there are 511 00:41:46,140 --> 00:41:49,920 là những gì ừ ranh giới mà họ là gì what are the um what are the boundaries that they 512 00:41:49,920 --> 00:41:55,500 rằng họ cảm thấy thoải mái khi sử dụng ternary các toán tử trong ternary có thể trở nên rất that they feel comfortable using ternary operators within ternary can become very 513 00:41:55,500 --> 00:41:58,920 phức tạp đặc biệt nếu bạn đang làm tổ chúng nếu bạn đang sử dụng một ngôi sao ba ngôi bên trong complicated especially if you're nesting them if you're using a ternary inside 514 00:41:58,920 --> 00:42:03,780 iternary và thật tốt khi kiểm tra với mọi người điều họ cảm thấy thoải mái iternary and it's just good to check with people what they're comfortable 515 00:42:03,780 --> 00:42:09,000 được rồi nhưng chúng ta hãy nhìn vào một toán tử bậc ba, giả sử hãy là H with okay but let's just have a look at a ternary operator let's say let's a H 516 00:42:09,000 --> 00:42:15,599 là 30. bây giờ hãy nói rằng bạn muốn hiển thị một thông báo cho người dùng nói is 30. now let's say that you want to display a message to the user saying 517 00:42:15,599 --> 00:42:22,520 hãy nhắn tin và sau đó bạn muốn nói nếu tuổi lớn hơn hoặc bằng 18 that let's message and then you want to say if the age is over or equal to 18 518 00:42:22,520 --> 00:42:30,200 thì tin nhắn này sẽ cho biết bạn là một Tuy nhiên, người lớn nếu độ tuổi dưới 18 then this message should say you are an adult however if the age is less than 18 519 00:42:30,200 --> 00:42:34,140 thì bạn nên nói rằng bạn chưa phải là một người lớn then you should say you are not yet an adult 520 00:42:34,140 --> 00:42:39,599 bạn làm tốt việc này bằng cách nào bạn có thể làm là nói tin nhắn của chúng ta là một chuỗi how do you do this well what you could do is to say let's message is a string 521 00:42:39,599 --> 00:42:45,480 được rồi ừ và sau đó bạn có thể nói nếu okay uh and then you could say if 522 00:42:45,480 --> 00:42:52,800 H lớn hơn hoặc bằng 18 thì tin nhắn là bạn đã trưởng thành H is more than or equal to 18 then message is you are an adult 523 00:42:52,800 --> 00:42:59,700 nếu không hãy nhắn tin vì bạn chưa phải là người lớn nên cái này thực sự hoạt động rất tốt otherwise message as you are not yet an adult so this works actually very well 524 00:42:59,700 --> 00:43:03,180 và bạn có thể gõ tin nhắn ra bạn có thể xem nào, nó nói rằng bạn không đơn giản chút nào and you can type the message out you can see now it says you are not all simply 525 00:43:03,180 --> 00:43:09,180 bởi vì H là 30 hoặc nếu bạn 16 thì nó sẽ nói bạn chưa phải là người lớn hoặc because the H is 30 or if you were 16 it would say you are not an adult yet or 526 00:43:09,180 --> 00:43:13,800 bạn chưa phải là người lớn tuy nhiên có một cách viết khác you're not yet an adult however there's another way of writing 527 00:43:13,800 --> 00:43:18,660 cùng một mã chính xác vậy nên chúng ta hãy bình luận cái này được rồi và đó là sử dụng the same exact code so let's just comment this out okay and that is using 528 00:43:18,660 --> 00:43:22,380 toán tử bậc ba nên ở đây bạn có thể hãy xem chúng tôi đã xác định biến của mình trước và the ternary operator so in here you can see we've defined our variable first and 529 00:43:22,380 --> 00:43:25,740 thì chúng ta sẽ sử dụng câu lệnh if và một câu lệnh khác rồi gán then we're going using an if statement and an else statement and then assigning 530 00:43:25,740 --> 00:43:31,859 giá trị cho biến đó được thôi, tuy nhiên bạn cũng có thể nói hãy nhắn tin cho bạn nhé values to that variable okay however you can also say let's message is then you 531 00:43:31,859 --> 00:43:36,599 bạn sẽ ghi tình trạng của bạn vào đây bạn nói tình trạng would put your condition in here you say condition 532 00:43:36,599 --> 00:43:40,560 được rồi và sau đó định dạng là bạn đặt một okay and then the format is then you put a 533 00:43:40,560 --> 00:43:44,460 dấu hỏi thì bạn nói giá trị nếu tình trạng question mark then you say value if condition 534 00:43:44,460 --> 00:43:48,660 được đáp ứng và sau đó hãy đặt cái này sang cái tiếp theo is met and then so let's put this to the next 535 00:43:48,660 --> 00:43:57,540 dòng và sau đó là dấu hai chấm ở đây và giá trị nếu điều kiện không được đáp ứng line and then a colon in here and value if the condition is not met 536 00:43:57,540 --> 00:44:01,740 vậy đây là định dạng của một ternary toán tử trước tiên bạn đặt điều kiện của mình vào so this is the format of a ternary operator first you put your condition in 537 00:44:01,740 --> 00:44:07,319 ở đây vậy điều kiện là gì vậy nếu tuổi lớn hơn hoặc bằng 18 nên chỉ cần here so what is the condition so if the age is more than or equal to 18 so just 538 00:44:07,319 --> 00:44:12,480 hãy viết nó tuổi nên nhiều hơn hơn hoặc bằng 18. thì ta nói rằng let's just write it age should be more than or equal to 18. then we say that 539 00:44:12,480 --> 00:44:17,880 giá trị phải là bạn là người lớn thì giá trị nếu điều kiện không the value should be you are an adult then the value if the condition is not 540 00:44:17,880 --> 00:44:24,000 tệ là bạn chưa phải là người lớn và điều đó chính xác là cách bạn viết một ternary bad is you are not yet an adult and that is exactly how you write a ternary 541 00:44:24,000 --> 00:44:28,140 nhà điều hành vì vậy bạn nói rằng bạn lấy biến mà bạn thực sự muốn operator so you say you take your variable that you want to actually 542 00:44:28,140 --> 00:44:33,119 tính giá trị của sau đó bạn nói nó bằng thì bạn đặt điều kiện của calculate the value of then you say it's equal to then you put the condition of 543 00:44:33,119 --> 00:44:36,960 toán tử bậc ba của bạn và sau đó là một dấu chấm hỏi nối tiếp dấu chấm hỏi your ternary operator and then a question mark after a question mark 544 00:44:36,960 --> 00:44:39,839 tuân theo giá trị mà bạn muốn gán cho biến của bạn follows the value that you want to assign to your variable 545 00:44:39,839 --> 00:44:45,300 nếu điều kiện được đáp ứng và sau đó dấu hai chấm và giá trị mà bạn muốn should the condition be met and then a colon and the value that you want to 546 00:44:45,300 --> 00:44:48,540 gán cho biến nên điều kiện chưa được đáp ứng được, còn bạn assign to the variable should the condition not have been met okay and you 547 00:44:48,540 --> 00:44:52,260 bây giờ có thể xem các tin nhắn bạn là một người lớn và nếu bạn thay đổi giá trị này một lần nữa can see now the messages you are an adult and if you change this value again 548 00:44:52,260 --> 00:44:58,200 đến 17 bạn có thể thấy giá trị sẽ là đổi thành bạn chưa phải là người lớn nhé to 17 you can see the value will be changed to you're not yet an adult okay 549 00:44:58,200 --> 00:45:02,040 Vì thế Tôi hy vọng bây giờ bạn đã có ý tưởng về so I hope that you've now got an idea of 550 00:45:02,040 --> 00:45:07,200 một số toán tử trong Swift mà chúng tôi đã có xem xét các loại toán tử khác nhau some operators in Swift you've we've had a look at different types of operators 551 00:45:07,200 --> 00:45:14,520 trong tiền tố đơn nhất hậu tố đơn nhất chúng ta có trung tố nhị phân và chúng tôi cũng đã xem xét một in unary prefix unary postfix we have binary infix and we've also looked at a 552 00:45:14,520 --> 00:45:20,040 loại toán tử thứ tư là toán tử bậc ba và một lần nữa chỉ là một fourth category of operators which are ternary operators and again just be a 553 00:45:20,040 --> 00:45:22,740 cẩn thận một chút với ternary các nhà khai thác vì không có nhiều little bit careful with ternary operators because not a lot of 554 00:45:22,740 --> 00:45:28,200 các nhà phát triển thực sự rất thoải mái sử dụng những thứ này tôi đã gặp, cá nhân tôi thích developers are actually very comfortable using these I met I personally like 555 00:45:28,200 --> 00:45:33,660 ternary đặc biệt thích trong những trường hợp này chỗ nào ít code hơn là điều dễ hiểu ternary especially like in these cases where is less code is understandable 556 00:45:33,660 --> 00:45:38,940 nó nhỏ gọn và không logic lắm tuy nhiên một số nhà phát triển chỉ viết chúng it's compact is not so much logic however some developers just write them 557 00:45:38,940 --> 00:45:43,619 tất cả trong một dòng như thế này và điều đó có thể hơi khó đọc một chút tôi tôi all in one line like this and that can be a little bit difficult to read I I 558 00:45:43,619 --> 00:45:49,680 thực sự đồng ý rằng thói quen của tôi trong Swift là bằng tay actually agree my uh habits in Swift is to manually 559 00:45:49,680 --> 00:45:54,060 chia mã của tôi thành các bit nhỏ hơn và những mảnh như thế này thành các dòng khác nhau như break my code down into smaller bits and pieces like this into different lines as 560 00:45:54,060 --> 00:45:57,359 Tốt tiếc là không giống một số người khác well unfortunately unlike some other 561 00:45:57,359 --> 00:46:02,940 ngôn ngữ lập trình như Rust và Dart và không có máy phân tích nội bộ vì programming languages like rust and dart and there is no internal analyzer as 562 00:46:02,940 --> 00:46:08,280 thật xin lỗi vì không có bộ định dạng nên Swift Code bạn cần định dạng bằng tay such sorry there are no formatter so Swift Code you need to format it by hand 563 00:46:08,280 --> 00:46:13,380 thật không may và nó đã được tám năm kể từ khi Swift xuất hiện và unfortunately and it has been eight years since Swift's come out and 564 00:46:13,380 --> 00:46:18,420 vẫn chưa có bộ định dạng nội bộ cho Swift tất nhiên bạn có thể chọn mã của mình there is still no internal formatter for Swift of course you can select your code 565 00:46:18,420 --> 00:46:23,640 và sau đó thụt mã của bạn bằng Ctrl I trong xcode and then indent your code with Ctrl I in xcode 566 00:46:23,640 --> 00:46:29,700 nhưng bạn không thể có định dạng xcode của mình mã cho bạn khi bạn gõ nên đó là một but you cannot have xcode format of your code for you as you type so that is a 567 00:46:29,700 --> 00:46:35,460 một chút vấn đề đáng tiếc mà chúng ta phải giải quyết nhưng đó là điều little bit of an unfortunate problem that we have to deal with but it is what 568 00:46:35,460 --> 00:46:38,819 nó là như vậy và chúng ta có thể làm quen với nó nếu bạn muốn tạo mã của mình một chút it is and we can just get used to it so if you want to make your code a little 569 00:46:38,819 --> 00:46:42,960 dễ đọc hơn một chút, tôi khuyên bạn nên định dạng nó một chút bằng tay thật tốt bit more readable I suggest that you format it a little bit by hand so kind 570 00:46:42,960 --> 00:46:48,960 làm thủ công cũng được đó thực sự là dành cho người vận hành nên of handcrafted as well okay that was really it for the operators so 571 00:46:48,960 --> 00:46:54,839 trong phần tiếp theo chúng ta sẽ xem xét nếu có tuyên bố khác vậy hẹn gặp bạn ở đó in the next section we're gonna look at if an else statement so see you there 572 00:46:54,839 --> 00:46:59,520 bây giờ chúng ta đã hoàn tất việc sử dụng các toán tử, hãy hãy tiếp tục và tạo một sân chơi mới hoặc now that we're done with operators let's go ahead and create a new playground or 573 00:46:59,520 --> 00:47:04,200 nếu và nếu không thì ngay tại đây tôi sẽ nhấn lệnh n if and else so right here I'm going to press command n 574 00:47:04,200 --> 00:47:09,780 trên MacIntosh và giả sử sân chơi trong ở đây rất tiếc nếu tôi có thể đánh vần nó và một khoảng trống on MacIntosh and let's say playground in here oops if I can spell it and a blank 575 00:47:09,780 --> 00:47:13,260 sân chơi và hãy gọi nó nếu playground and let's just call it if 576 00:47:13,260 --> 00:47:16,140 khác và vui lòng đảm bảo rằng bạn không else and please just ensure that you're not 577 00:47:16,140 --> 00:47:19,619 tạo ra nó bên trong một sân chơi hiện có bạn có thể creating it inside an existing playground you can 578 00:47:19,619 --> 00:47:24,480 hãy xem ở đây nó được gọi là toán tử và chúng tôi nên thay đổi điều đó thành bên trong chính của chúng tôi see in here it's called operators and we should change that to be inside our main 579 00:47:24,480 --> 00:47:29,579 thư mục về cơ bản là được và sau đó chúng ta nói điều đó không nên ở trong nhóm khai thác folder basically okay and then we say it shouldn't be inside the operators group 580 00:47:29,579 --> 00:47:35,339 hoặc nó phải ở trong nhóm op Không gian làm việc ARP nên hãy tạo ngay bây giờ chúng ta có thể either it should be inside the group op ARP workspace so create now we can 581 00:47:35,339 --> 00:47:39,960 thu gọn những cái khác và ở đây chỉ như bình thường chúng tôi nói kem nền không thích collapse the other ones and in here just like normal we say foundation not like 582 00:47:39,960 --> 00:47:43,079 bình thường thực ra là như thường lệ ý tôi là nói normal actually like usual I meant to say 583 00:47:43,079 --> 00:47:46,980 vậy hãy nói về nếu và khác những tuyên bố chúng tôi đã thấy một vài so let's talk about if and else statements we've already seen a few 584 00:47:46,980 --> 00:47:51,240 ví dụ về nếu và khác và nếu bạn đã lập trình xong ở nơi khác rồi examples of if and else and if you've already done programming in another 585 00:47:51,240 --> 00:47:55,020 ngôn ngữ lập trình bạn nên có làm quen với cái gì nếu và cái gì khác programming language you should already be familiar with what if and else 586 00:47:55,020 --> 00:47:59,640 tuyên bố là như vậy nó chỉ là một về cơ bản có điều kiện được rồi, hãy thêm một statements are so it's just a conditional basically okay let's add a 587 00:47:59,640 --> 00:48:03,480 có vài giá trị ở đây nên tôi sẽ chuyển sang sao chép và dán một số giá trị và đặt few values in here so I'm just going to copy and paste some values and place 588 00:48:03,480 --> 00:48:08,460 chúng ở đây để có một số giá trị hạt giống mà chúng tôi có thể làm việc với Được rồi, hãy tạo một thứ đơn giản them in here so some seed values that we can work with Okay let's create a simple 589 00:48:08,460 --> 00:48:14,040 câu lệnh if và sau đó if xin lỗi và if an câu lệnh khác nên chúng tôi nói nếu tên tôi là if statement and then if sorry an if an else statement so we say if my name is 590 00:48:14,040 --> 00:48:21,000 bằng nhau có giá trị như nhau nên ở đây như thế này và thế này là sử dụng một equal equal valid so in here so like this and so this is using a 591 00:48:21,000 --> 00:48:26,819 chữ v thường như bạn thấy ở đây nhé sau đó chúng tôi nói tên bạn là và sau đó chúng tôi lowercase v as you can see in here okay then we say your name is and then we're 592 00:48:26,819 --> 00:48:30,900 sẽ thêm biến của chúng tôi trong một chuỗi và đây là cách bạn thực hiện điều đó going to add our variable within a string and this is how you do it in so 593 00:48:30,900 --> 00:48:35,460 nếu bạn nói dấu gạch chéo ngược và sau đó dấu ngoặc đơn và sau đó bạn nói tên tôi trong if you say back backslash and then parenthesis and then you say my name in 594 00:48:35,460 --> 00:48:40,380 ở đây được rồi thì ở đây chúng ta có thể nói khác và không here okay then in here we can say else and with no 595 00:48:40,380 --> 00:48:43,020 điều kiện ở phía trước nó và sau đó chúng tôi nói ôi conditions in front of it and then we say oops 596 00:48:43,020 --> 00:48:50,160 Tôi đoán là tôi đã đoán sai như thế này và sau đó hãy chạy tự động cho I guessed I guessed it wrong like this and then let's do an automatic run for 597 00:48:50,160 --> 00:48:54,660 sân chơi của chúng tôi và bây giờ chúng ta nên đến phần rất tiếc vì chúng tôi đã đoán our playground and we should now come to the oops part because we guessed the 598 00:48:54,660 --> 00:48:58,920 tên không chính xác với chữ v viết thường bạn có thể thấy ở đây vì vậy đây là một cách đơn giản name incorrectly with a lowercase v as you can see in here so this is a simple 599 00:48:58,920 --> 00:49:03,359 câu lệnh if để bạn so sánh một cái gì đó với ừ với cái gì khác và sau đó bạn if statement so you compare something with uh with something else and then you 600 00:49:03,359 --> 00:49:07,500 có thể có một khối khác hoặc không bạn có thể thực ra chỉ có một câu lệnh if như can have an else block or not you can actually just have an if statement as 601 00:49:07,500 --> 00:49:11,040 ồ vậy nên bạn không cần phải có cái khác Chặn trong Swift được rồi well so you don't have to have an else Block in Swift okay 602 00:49:11,040 --> 00:49:16,380 bây giờ bạn không bị giới hạn trong bạn nữa chỉ giới hạn ở một tuyên bố khác mà bạn now you're not limited in you're not limited only to one else statement you 603 00:49:16,380 --> 00:49:22,040 không thể có cái khác nếu được, vậy nên hãy chỉ cần nói nếu can't have else if as well okay so let's just say if 604 00:49:22,040 --> 00:49:28,020 tên tôi tên tôi bằng nhau bằng đất liền với cách viết đúng chính tả cũng như với một my name my name is equal equal land up with the proper spelling as well with a 605 00:49:28,020 --> 00:49:33,780 viết hoa V thì chúng ta nói bây giờ tôi đoán rồi chính xác được rồi capital V then we say now I guessed it correctly okay 606 00:49:33,780 --> 00:49:37,980 và sau đó chúng tôi nói khác nếu tên của tôi and then we say else if my name 607 00:49:37,980 --> 00:49:42,960 là Foo bây giờ bạn có thể thấy rằng chúng tôi có một Chi nhánh khác vì vậy chúng tôi có if và then is Foo now you can see that we have another Branch so we have an if and then 608 00:49:42,960 --> 00:49:48,119 nếu trường hợp đó không được đáp ứng thì chương trình sẽ rơi vào tuyên bố này vì vậy nó if that case is not met then the program will fall into this statement so it's 609 00:49:48,119 --> 00:49:51,960 rất quan trọng để hiểu rằng đó là không phải Swift đang thực thi cả hai very important to understand that it's not that Swift is executing both of 610 00:49:51,960 --> 00:49:56,880 đồng thời nó đang thực thi đầu tiên trước nếu điều kiện đó được đáp ứng these concurrently it's executing the first one first if that condition is met 611 00:49:56,880 --> 00:50:00,720 sau đó Swift vào đây và bỏ qua tất cả mọi thứ tất cả các tuyên bố khác then Swift goes in here and ignores everything all the other statements 612 00:50:00,720 --> 00:50:05,640 bên trong các câu lệnh if nên tất cả các if khác và câu lệnh L cuối cùng inside the if statements so all the other else ifs and the last L statement 613 00:50:05,640 --> 00:50:10,680 nếu nó có sẵn thì chỉ vậy thôi phân nhánh về cơ bản là được if it is available so it's just branching basically okay 614 00:50:10,680 --> 00:50:15,839 vậy nếu tên tôi là Foo như chúng tôi gọi bạn là Foo và điều này thực sự không quan trọng so if my name is Foo as we say are you Foo and this doesn't really matter what 615 00:50:15,839 --> 00:50:19,680 bạn gõ vào đây tôi chỉ đang cố gắng chứng minh làm thế nào nếu và khác nếu về cơ bản you type in here I'm just trying to demonstrate how if and else if basically 616 00:50:19,680 --> 00:50:23,700 các câu lệnh hoạt động trong Swift và sau đó chúng ta có thể có một tuyên bố khác cuối cùng ở đây và statements work in Swift and then we can have a final else statement in here and 617 00:50:23,700 --> 00:50:29,060 nói được thôi tôi từ bỏ được rồi và bạn có thể thấy Swift đã đi vào says okay I give up okay and you can see that Swift has gone into 618 00:50:29,060 --> 00:50:34,440 Chi nhánh này vì tên đã chính xác đặt thành Van Dot và chúng tôi đang so sánh nó this Branch because name was correctly set to Van Dot and we're comparing it 619 00:50:34,440 --> 00:50:38,880 với vandan xin lỗi, nó không được đặt thành Vanda Ý tôi là nó được đặt ở đây nhưng chúng ta with vandan sorry it wasn't set to Vanda I mean it was set in here but we're 620 00:50:38,880 --> 00:50:43,140 thực sự so sánh nó một cách chính xác với giá trị đúng ở đây được rồi và một số actually comparing it correctly with the correct value in here okay and some 621 00:50:43,140 --> 00:50:47,460 mọi người viết câu lệnh if của họ a nhiều hơn một chút giống như những gì tôi gọi là people write their if statements a little bit more in like what I call a 622 00:50:47,460 --> 00:50:52,260 lộn ngược và ở đây bạn có thể thấy chúng tôi nói rằng nếu tên của tôi bằng Vandal và flipped way and here you can see we're saying if my name is equal to Vandal and 623 00:50:52,260 --> 00:50:55,500 vì vậy nếu bạn đang đọc nó như bạn sẽ đọc một câu tiếng Anh tôi sẽ nói nếu so if you're reading it like you would read an English sentence I would say if 624 00:50:55,500 --> 00:51:00,300 tên của tôi bằng hợp lệ tuy nhiên một số mọi người thực sự làm điều đó ngược lại my name is equal to valid however some people actually do it in the opposite 625 00:51:00,300 --> 00:51:07,079 theo cách này họ sẽ nói nếu van dot tương đương với khai thác nên đây là một cái khác way like this they would say if van dot is equal to mining so this is another 626 00:51:07,079 --> 00:51:13,020 cách viết nó một cách không phổ biến làm điều này và rất cũ và giống như một way of writing it an uncommon way of doing this and a lot of old and like a 627 00:51:13,020 --> 00:51:17,640 các nhà phát triển trường học cũ một chút sẽ làm những việc như thế này nó không phổ biến lắm little bit old school developers would do stuff like this it is not so common 628 00:51:17,640 --> 00:51:22,260 trong tất cả những năm tôi làm việc ở lĩnh vực phần mềm kỹ sư tôi đã gặp một hoặc hai người in all my years of working as a software engineer I've seen one or two people 629 00:51:22,260 --> 00:51:26,839 tuy nhiên thích cái này hơn tôi và đồng nghiệp của tôi đã có thể preferring this however me and my colleagues have been able to 630 00:51:26,839 --> 00:51:31,500 thuyết phục họ bằng cách khác rằng đây là điều này chúng ta không nên làm điều này trong hầu hết thời hiện đại convince them otherwise that this is this we shouldn't do this in most modern 631 00:51:31,500 --> 00:51:36,960 Mã nguồn không làm điều này tuy nhiên bạn có thể là một ngoại lệ nên có thể bạn Source codes don't do this however you may be an exception in so maybe you're 632 00:51:36,960 --> 00:51:41,280 làm việc tại một công ty nơi đây là cách phổ biến để thực hiện các câu lệnh if trong working at a company where this is the prevalent way of doing if statements in 633 00:51:41,280 --> 00:51:46,680 rằng bạn thực sự đặt giá trị và điều đó bạn và đang thử nghiệm that you actually put the value and that you and are testing 634 00:51:46,680 --> 00:51:52,619 ừm cuối cùng và sau đó bạn so sánh với giá trị và bạn đang mong đợi đầu tiên như um last and then you compare with the value and that you're expecting first as 635 00:51:52,619 --> 00:51:56,220 Tôi đã nói điều này hơi hiếm ở kinh nghiệm của tôi nhưng có lẽ ở công ty I said this is a little bit uncommon in my experience but maybe at the company 636 00:51:56,220 --> 00:52:00,960 rằng bạn là bạn và đồng đội của bạn có quyết định rằng đây là cách để làm điều đó that you are you and your teammates have decided that this is the way to do it it 637 00:52:00,960 --> 00:52:07,319 hoàn toàn bằng cái này, nó là điều tương tự như mã này và ý tôi là gì is completely equal to this it is the same thing as this code and I mean what 638 00:52:07,319 --> 00:52:11,760 nó đạt được là như nhau tuy nhiên cú pháp hơi khác một chút được rồi it achieves is the same however the syntax is a little bit different okay so 639 00:52:11,760 --> 00:52:17,700 điều đó tùy thuộc vào bạn và đồng đội của bạn tuy nhiên hãy quyết định xem nên làm theo cách nào it is up to you and your teammates to decide what which way to do however 640 00:52:17,700 --> 00:52:24,780 nếu bạn chưa quen với Swift, tôi xin bạn xin vui lòng không làm điều này và nó là như vậy if you're new to Swift I beg you to please don't do this and it is this way 641 00:52:24,780 --> 00:52:29,040 rằng bạn nên học cách viết các câu lệnh if vì vậy xin đừng lật chúng that you should learn how to write your if statements so please don't flip these 642 00:52:29,040 --> 00:52:33,420 Tuy nhiên, giá trị nếu bạn là người dày dạn nhà phát triển và bạn biết chính xác những gì values however if you're a seasoned developer and you know exactly what 643 00:52:33,420 --> 00:52:38,579 bạn đang làm và bạn và đồng đội của bạn đã quyết định rằng trong cơ sở mã của bạn tất cả you're doing and you and your teammates have decided that in your code base all 644 00:52:38,579 --> 00:52:42,900 câu lệnh if của bạn nên được viết như thế này hoặc chỉ trong một vài ngoại lệ your if statements should be written like this or in just a few exception 645 00:52:42,900 --> 00:52:46,079 trường hợp bạn viết mã của mình như thế này miễn là bạn đã kiểm tra với nhóm của mình là cases you write your code like this as long as you've checked with your team is 646 00:52:46,079 --> 00:52:49,619 và mọi thứ đều ổn thì bạn cứ tiếp tục và làm điều đó nhưng nếu bạn đang học Swift and everything is fine then you go ahead and do it but if you're learning Swift 647 00:52:49,619 --> 00:52:54,359 ngay bây giờ đây là cách để viết nếu tuyên bố được rồi và đây là cách mà just now this is the way to write an if statement okay and this is the way that 648 00:52:54,359 --> 00:52:59,520 hầu hết mọi người đều viết nếu tuyên bố dày dạn hoặc không dày dạn almost everyone writes their if statements seasoned or not seasoned 649 00:52:59,520 --> 00:53:05,579 tốt, thật đơn giản, đây là một số câu lệnh if đơn giản về cơ bản so sánh good so that was simple these are some simple if statements basically comparing 650 00:53:05,579 --> 00:53:09,359 một giá trị với một giá trị khác nhưng nếu bạn đang có nhiều hơn một chút a value with another value but what if you are having a little bit more 651 00:53:09,359 --> 00:53:13,740 logic phức tạp ở đây vì vậy hãy nói rằng bạn muốn chắc chắn complicated logic in here so let's say that you want to make sure 652 00:53:13,740 --> 00:53:18,300 rằng tên của bạn đã bị phát hiện và điều đó tuổi của bạn cũng là 30. vì vậy bạn có thể thấy that your name is found out and that your age is also 30. so you can see the 653 00:53:18,300 --> 00:53:22,500 tuổi được định nghĩa ở đây là 20. chúng ta hãy chỉ thay vào đó hãy tiếp tục và so sánh nó với 30 age is defined in here as 20. let's just go ahead and compare it with 30 instead 654 00:53:22,500 --> 00:53:27,300 hãy nói nếu tên của tôi và ở đây nếu bạn cũng muốn so sánh let's say if my name and in here if you want to compare also 655 00:53:27,300 --> 00:53:33,059 độ tuổi bạn có thể nói và chẳng hạn như tuổi của tôi là 30 được rồi chúng ta the age you can say and my age is 30 for instance okay then we 656 00:53:33,059 --> 00:53:40,680 nói tên là chủ nhà và tuổi là 30. thì chúng ta sẽ nói khác nếu tuổi của tôi là 20 thì chúng ta say name is landlord and age is 30. then we say else if a my age is 20 then we 657 00:53:40,680 --> 00:53:47,280 nói là tôi chỉ đoán đúng tuổi thôi một tuyên bố khác ở đây chúng ta có thể nói tôi say I only guess the age right and then an else statement in here we can say I 658 00:53:47,280 --> 00:53:51,359 đừng biết tôi đang làm gì cũng được, như bạn muốn don't know what I'm doing okay so as you'd 659 00:53:51,359 --> 00:53:55,440 mong đợi bây giờ chúng ta sẽ đi sâu vào vấn đề này dòng mã vậy điều đang xảy ra ở đây là expect now we're going to go into this line of code so what's happening here is 660 00:53:55,440 --> 00:53:59,460 rằng Swift đã bắt đầu thực thi mã này từ trái sang phải và tôi nói ổn từ that Swift started executing this code from left to right and I said okay from 661 00:53:59,460 --> 00:54:05,520 để lại cái tên thực sự là vandot và nó bắt đầu so sánh tuổi tác và điều đó nói rằng left the name is truly vandot and it started comparing the age and that says 662 00:54:05,520 --> 00:54:11,640 tuổi thực sự là 20 chứ không phải 30 nên tôi không sẽ đi sâu vào câu lệnh if này age is indeed 20 is not 30 so I'm not going to go into this if statement so it 663 00:54:11,640 --> 00:54:15,480 bỏ qua điều này nếu sau đó nó nhìn vào mã theo sau câu lệnh if này và ignores this if then it looks at the code that follows this if statement and 664 00:54:15,480 --> 00:54:21,720 nói ồ đó là một cái khác nếu không thì tuổi là 20 là tuổi 20 đúng rồi đó says oh it's an else otherwise if the age is 20 is the age 20 yes it is then 665 00:54:21,720 --> 00:54:26,280 nó rơi vào tuyên bố này và sau đó bỏ qua phần còn lại của người khác it falls into this statement and then ignores the rest of the else 666 00:54:26,280 --> 00:54:31,020 vì vậy bạn cần phải nghĩ đến các câu lệnh if như trong các nhánh và chúng bị xử tử so you need to think of if statements as in branches and they get executed 667 00:54:31,020 --> 00:54:37,740 riêng biệt không đồng thời và chúng về cơ bản theo thứ tự nối tiếp từ separately not concurrently and they're basically in a Serial order from the 668 00:54:37,740 --> 00:54:41,760 tuyên bố đầu tiên nếu nó thất bại đi đến câu lệnh tiếp theo sau đó chuyển sang câu lệnh tiếp theo first statement if it fails goes to the next statement then goes to the next 669 00:54:41,760 --> 00:54:47,940 tuyên bố nếu bất kỳ tuyên bố nào trong số này thành công trong việc bẫy logic nên điều này statement if any of these statements succeed in trapping the logic so this 670 00:54:47,940 --> 00:54:53,339 một người bị mắc kẹt và nói không sao nếu tuổi là 20 và trong đó thực sự có mã one trapped and said okay if the age is 20 and in it is indeed then the code 671 00:54:53,339 --> 00:54:58,200 đi vào đây nếu có bất kỳ cái nào khác câu lệnh hoặc nếu câu lệnh làm điều đó goes in here if any of these else statements or if statements do that the 672 00:54:58,200 --> 00:55:04,740 toàn bộ phần còn lại của mã này sau đó sẽ bị bỏ qua vì vậy điều này không rơi vào nên chúng tôi entire rest of this code is then ignored so this didn't fall into so this we 673 00:55:04,740 --> 00:55:08,819 đã không rơi vào điều này chúng tôi đã rơi vào cái này và phần còn lại hoàn toàn didn't fall into this we did fall into this and then the rest is completely 674 00:55:08,819 --> 00:55:13,140 bị bỏ qua bất kể có bao nhiêu người khác bạn có ở đây bạn có thể nói khác nếu ignored regardless of how many else's you have in here you can say else if 675 00:55:13,140 --> 00:55:17,400 blah blah và sau đó là một cái khác nữa nhưng tất cả những điều đó sẽ bị bỏ qua blah blah and then another else after that but all of those will be ignored 676 00:55:17,400 --> 00:55:21,420 được rồi bây giờ giống như chúng ta có toán tử trong okay now just like we have the an operator in 677 00:55:21,420 --> 00:55:27,000 ở đây chúng ta cũng có toán tử logic và có toán tử or được nhưng bạn cần here the logical and operator we also have the or operator okay but you need 678 00:55:27,000 --> 00:55:32,220 hãy cẩn thận với nó bởi vì bạn có thể thực sự tạo mã và làm mọi việc to be careful with it because you can actually make the code and do things 679 00:55:32,220 --> 00:55:36,540 rằng bạn không muốn điều đó xảy ra vậy nên hãy để tôi chỉ cần giải thích điều gì đó ở đây that you didn't want it to do so let me just explain something in here 680 00:55:36,540 --> 00:55:47,099 vì vậy hãy viết một ví dụ giả sử nếu H của tôi là 20 chứ không phải 200 hoặc tên tôi là Foo so let's write an example let's say if my H is 20 not 200 or my name is Foo 681 00:55:47,099 --> 00:55:54,720 thì ta nói tuổi là 20 tên là Foo hoặc cả hai then we say either age is 20 name is Foo or both 682 00:55:54,720 --> 00:55:59,220 vậy điều xảy ra ở đây là bạn có thể thấy chúng tôi nói bạn có thể đang đọc cái này so what happening here is that you can see we say you may be reading this 683 00:55:59,220 --> 00:56:04,619 nói tuổi là 20 hoặc tên là Foo nhưng Swift đọc gì ở đây saying either the age is 20 or the name is Foo but what Swift does reading here 684 00:56:04,619 --> 00:56:10,260 nói tên ở tuổi 20 hoặc tên là ai hoặc cả hai người này nên thậm chí says either the name at the age is 20 or the name is who or both of these so even 685 00:56:10,260 --> 00:56:15,240 nếu cả hai điều này đều đúng thì mã này được thực thi và lý do đằng sau đó if both of these are true then this code is executed and the reason behind that 686 00:56:15,240 --> 00:56:22,020 đó là nếu tuổi của bạn là 20 thì mã thực ra nó đến đây theo mặc định is that if your age is 20 then the code actually comes here just by default it 687 00:56:22,020 --> 00:56:27,900 thậm chí không thực hiện phần còn lại được rồi, đó là lý do nếu tuổi doesn't even execute the rest okay so that is the reason that if age 688 00:56:27,900 --> 00:56:32,880 20 tuổi, tên bạn thực sự có thể là Foo và đó là những gì bạn đã viết ở đây nhưng is 20 your name might indeed be Foo and that is what you've written in here but 689 00:56:32,880 --> 00:56:36,900 mã đã rơi vào trường hợp này rồi đơn giản vì phần đầu tiên của the code has already fallen into this simply because the first part of the 690 00:56:36,900 --> 00:56:41,700 điều kiện đã được đáp ứng nên Swift thậm chí không thực hiện phần này nó nói ồ tuổi 20 condition was met so Swift doesn't even execute this part it says oh ages 20 of 691 00:56:41,700 --> 00:56:45,960 tất nhiên hãy vào đây được rồi đơn giản thôi bởi vì Swift nhìn vào ứng dụng tuyên bố course let's go in here okay simply because Swift looks at the statement app 692 00:56:45,960 --> 00:56:50,339 so với ồ đã nói hay thế thì tôi không cần phải làm vậy thực hiện nó đơn giản vì tôi đã biết versus oh said or so I don't have to execute it simply because I already know 693 00:56:50,339 --> 00:56:57,599 rằng tuổi của tôi là 20 nên nó rơi vào đây được rồi vì vậy nó có thể là phần này phần này that my age is 20 so it falls here okay so it can be either this part this one 694 00:56:57,599 --> 00:57:01,800 hoặc cả hai những người theo thuyết vật linh và các nhà phát triển tạo ra là họ or both animistics and developers make is they 695 00:57:01,800 --> 00:57:06,900 nghĩ rằng họ có thể thêm một cái khác Chặn ở đây và khối kia sẽ think that they can add another else Block in here and that else block will 696 00:57:06,900 --> 00:57:11,640 cũng được thực thi và đó không phải là trường hợp này vì như tôi đã giải thích trước đây be executed as well and that is not the case because as I've explained it before 697 00:57:11,640 --> 00:57:17,040 nếu các câu lệnh bằng 0 và chúng nhận được thực hiện từng cái một nếu bất kỳ trong số chúng if statements are zero and they get executed one at a time if any of them 698 00:57:17,040 --> 00:57:22,020 bẫy ừm ý nghĩa của việc thực hiện chương trình traps the um the execution of the program meaning 699 00:57:22,020 --> 00:57:27,240 rằng nó thực sự dẫn đến trình biên dịch hiểu rằng ồ chi nhánh này của that it actually results to the compiler understanding that oh this branch of 700 00:57:27,240 --> 00:57:31,500 mã nên được thực thi sau đó phần còn lại sẽ bị bỏ qua vì vậy nếu ở đây bạn gõ code should be executed then the rest will be ignored so if in here you type 701 00:57:31,500 --> 00:57:36,839 khác nếu tên tôi là Vân chấm ngay cả khi bạn điều kiện được đáp ứng mà trong trường hợp này là else if my name is Van dot even if your condition is met which in this case is 702 00:57:36,839 --> 00:57:43,859 bởi vì tên của tôi thực sự là vandad hoặc của tôi tuổi là 30 tôi bắt đầu ở tuổi 20 và điều đó đã được ấn định because my name is truly vandad or my age is 30 I started 20 which it was set 703 00:57:43,859 --> 00:57:48,780 lên đây nếu bạn nhớ tên và tuổi của tôi là van dot and20 up here if you remember my name and my age were van dot and20 704 00:57:48,780 --> 00:57:54,240 tương ứng mã này sẽ không được thực hiện vì vậy hãy nói rằng đã quá muộn để respectively this code will not be executed so let's say it's too late to 705 00:57:54,240 --> 00:57:58,020 vào lớp này bạn có thể thấy rằng sẽ không được thực thi nó sẽ không được hiển thị get in this class you can see that it won't be executed it won't be displayed 706 00:57:58,020 --> 00:58:02,640 ở đây chỉ có nhánh này được thực thi đơn giản vì tuổi của tôi là 20. được thôi và tôi in here only this branch is executed simply because my age was 20. okay and I 707 00:58:02,640 --> 00:58:07,500 thực sự có thể thay đổi nó thành Foo và bạn có thể thấy nó vẫn đến đây đầu tiên bởi vì can change it actually to Foo and you can see it still gets here first because 708 00:58:07,500 --> 00:58:13,619 tuổi của tôi là 20 và người điều hành sau đó là một logic hoặc có nghĩa là ồ nếu điều này my age is 20 and the operator after that is a logical or meaning that oh if this 709 00:58:13,619 --> 00:58:18,420 hoặc cái này hoặc cả hai và đó là vì cái này đúng là nó thậm chí không cần phải thực thi or this or both and it's since this one is true it doesn't even have to execute 710 00:58:18,420 --> 00:58:21,780 điều này được rồi Vì thế this okay so 711 00:58:21,780 --> 00:58:28,079 như tôi đã đề cập vâng hoặc thực sự có thể hoặc an và các toán tử logic mà họ có thể nhận được as I mentioned yeah or can actually or an and logical operators they can get 712 00:58:28,079 --> 00:58:33,839 khá phức tạp ở chỗ nếu bạn bạn đang làm việc với những người vận hành này và quite complicated in that if you're if you're working with these operators and 713 00:58:33,839 --> 00:58:40,440 cũng có dấu ngoặc đơn thì bạn có thể tạo cũng là loại mã khó hiểu và nếu also parenthesis then you could create kind of confusing code as well and if 714 00:58:40,440 --> 00:58:44,160 thực ra bạn không sử dụng dấu ngoặc đơn đôi khi logic của bạn có thể hoàn toàn you actually don't use parenthesis sometimes your logic could be completely 715 00:58:44,160 --> 00:58:47,220 không đúng, để tôi chỉ cho bạn xem ví dụ incorrect let me just show you an example 716 00:58:47,220 --> 00:58:52,619 hãy viết mã ở đây và chúng tôi nói nếu tên tôi là chủ nhà let's write a coding here and we say if my name is landlord 717 00:58:52,619 --> 00:58:59,400 sau đó chúng ta chuyển sang dòng tiếp theo và chúng ta nói và tuổi của tôi là 22. and then we go to the next line and we say and my age is 22. 718 00:58:59,400 --> 00:59:03,299 được rồi sau đó chúng ta chuyển sang dòng tiếp theo và okay then we go to the next line and your 719 00:59:03,299 --> 00:59:10,680 tên là Foo và hãy nhớ tên tôi là tôi 20 tuổi. Tên bạn là name is Foo and remember my name is my age is 20. your name is 720 00:59:10,680 --> 00:59:15,660 Foo ở tuổi bạn là 19. được rồi đây chúng tôi đang nói tên bạn là ai và chúng tôi Foo at your age is 19. okay then here we're saying your name is who and we 721 00:59:15,660 --> 00:59:21,059 biết rằng điều đó thực sự đúng hoặc tuổi của bạn know that that is true in fact or your age 722 00:59:21,059 --> 00:59:27,960 là 19. được rồi chúng ta nói vậy và đây là gì mã thực sự đang làm nên chúng tôi nói tên tôi là is 19. okay so we say and what is this code actually doing so we say my name is 723 00:59:27,960 --> 00:59:33,839 Tìm thấy tình yêu và tôi 22 tuổi và tên bạn là Foo Found Love and I'm 22 and your name is Foo 724 00:59:33,839 --> 00:59:37,619 ngu hoặc Foo or 725 00:59:37,619 --> 00:59:42,960 bạn 19 tuổi. bạn có thấy chuyện gì đang xảy ra không ở đây vậy chuyện đã xảy ra là thế và bạn you are 19. do you see what happening here so what happened was that and you 726 00:59:42,960 --> 00:59:46,380 có thể thấy rằng tin nhắn này thực sự là được in ở đây với ý nghĩa sân chơi của chúng tôi can see that this message actually is printed here in our playground meaning 727 00:59:46,380 --> 00:59:51,960 rằng mã đã rơi vào trường hợp này vụ hành quyết này Chi nhánh vậy chuyện gì đã xảy ra that the code did fall into this as into this execution Branch so what happened 728 00:59:51,960 --> 00:59:57,240 bạn có thể nói rằng tên tôi là Vanda và tôi tuổi là 22 nhưng bạn có thể nói rõ tuổi của bạn you can say that my name is Vanda and my age is 22 but you can say well your age 729 00:59:57,240 --> 01:00:02,339 không phải là 22. làm sao mã này lại đến được đây và lý do là vì chúng tôi đang trộn is not 22. how did this code come here and the reason is because we're mixing 730 01:00:02,339 --> 01:00:08,280 ands và quặng và bạn có thể thấy những gì Swift đọc ở đây nói được nếu bạn ands and ores and you can see what what Swift reads in here says okay if your 731 01:00:08,280 --> 01:00:13,380 tên là Văn Điểm và tuổi của bạn là 22. name is Van Dot and your age is 22. 732 01:00:13,380 --> 01:00:19,380 và tên của bạn là Foo điều này có đúng không nhìn tất cả những con kiến ​​này, đúng rồi and your name is Foo is this true then looks at all these ants this is yeah 733 01:00:19,380 --> 01:00:24,059 tên bạn là nhưng tuổi của bạn không phải là 22. sau đó nó nhìn vào phần còn lại mà nó có thể your name is but your age is not 22. then it looks at the rest that it could 734 01:00:24,059 --> 01:00:28,079 và nói tôi có logic nào khác để làm theo và nó nói có, thực ra bạn đã and says do I have any other logic to follow and it says yes actually you've 735 01:00:28,079 --> 01:00:34,020 đã viết nó ở đây hoặc tuổi của bạn phải là 19 và nó written it here either these or that your age should be 19 and it 736 01:00:34,020 --> 01:00:39,599 nhìn vào tuổi của bạn vậy ừ đúng vậy tuổi của bạn là 19. vì vậy bạn có thể thấy điều này như thế nào looks at your age so uh Yes actually your age is 19. so you can see how this 737 01:00:39,599 --> 01:00:43,140 có thể gây nhầm lẫn cho bạn khi đọc điều này bạn có thể nghĩ ồ tên bạn nên là could be confusing for you reading this you may think oh your name should be 738 01:00:43,140 --> 01:00:48,660 vandot và tuổi của bạn phải là 22 và tên của bạn phải là Foo hoặc tuổi của bạn vandot and your age should be 22 and your name should be Foo or your age 739 01:00:48,660 --> 01:00:52,319 phải là 90 nên bạn có thể nghĩ rằng cái này phần được thực hiện riêng biệt và phần này should be 90 so you may think that this part is executed separately and this 740 01:00:52,319 --> 01:00:56,760 một phần là riêng biệt nhưng vì không có dấu ngoặc đơn giữa những Swift này đọc nó part is separate but since there's no parenthesis between these Swift reads it 741 01:00:56,760 --> 01:01:03,599 từ trái sang phải và sau đó không có uh quyền ưu tiên giữa ands và quặng from left to right and then there's no uh precedence between the ands and ores 742 01:01:03,599 --> 01:01:07,260 vì vậy họ có cùng mức độ ưu tiên nên nó nói được thôi, toàn bộ chuyện này đều giống nhau so they have the same precedence so it says okay this entire thing is the same 743 01:01:07,260 --> 01:01:10,920 ưu tiên và tôi chỉ thực hiện nó từ trái sang phải precedence and I just execute it from left to right 744 01:01:10,920 --> 01:01:16,260 và điều này hoặc cuối cùng về cơ bản là bẫy nhánh thực thi và đảm bảo rằng and this or at the end basically traps the execution branch and ensures that 745 01:01:16,260 --> 01:01:20,579 mã rơi vào câu lệnh if được rồi viết mã như thế này có thể the code falls into the if statement okay so writing code like this could be 746 01:01:20,579 --> 01:01:26,460 một chút khó hiểu những gì bạn có thể thay vào đó đã muốn viết cái này a little bit confusing what you might have wanted to write is this instead 747 01:01:26,460 --> 01:01:31,559 bạn có thể muốn nói nếu và sau đó dấu ngoặc đơn được rồi you probably wanted to say if and then parenthesis okay 748 01:01:31,559 --> 01:01:35,819 và đây là logic của riêng bạn nên bạn về cơ bản muốn kiểm tra tên của bạn và and then this is your own logic so you want to basically check your name and 749 01:01:35,819 --> 01:01:40,859 tuổi nên hãy đặt nó trong ngoặc đơn vì vậy chúng tôi nói tên của tôi được thành lập age so let's put it inside parenthesis so we say my name is founded 750 01:01:40,859 --> 01:01:48,839 và chúng ta hãy chuyển sang slide tiếp theo và tuổi của tôi chắc là 22 nên về cơ bản thì bạn and let's go to the next slide and my age should be 22 so you're basically 751 01:01:48,839 --> 01:01:55,319 đang nói và thế là bạn nói tên tôi là Vandal và http 22. của tôi, sau đó bạn chuyển sang phần tiếp theo saying and so you say my name is Vandal and my http 22. then you go to the next 752 01:01:55,319 --> 01:02:00,480 dòng và bạn nói và và khác ngoặc tên của bạn line and you say and and another parenthesis your name 753 01:02:00,480 --> 01:02:08,940 là Foo hoặc tuổi của bạn là 19. như thế này được rồi is Foo or your age is 19. like this okay so 754 01:02:08,940 --> 01:02:14,280 chuyện đang xảy ra ở đây là ừ và tôi có thể thấy sân chơi của chúng tôi có vấn đề what is happening in here is uh and I can see our playground has some problem 755 01:02:14,280 --> 01:02:19,440 vậy điều này thực sự tương đương với ý tôi là nếu bạn muốn đọc nó bằng tiếng Anh, bạn có thể so what this really equates to I mean if you want to read it in English you could 756 01:02:19,440 --> 01:02:25,079 nói rằng tên của tôi được thành lập và tôi 22 tuổi. Và say my name is founded and I'm 22. and 757 01:02:25,079 --> 01:02:28,940 tên bạn là Foo your name is Foo 758 01:02:28,980 --> 01:02:34,500 hoặc bạn 19 tuổi. vậy bạn có thấy điều này thế nào không khác biệt tên bạn và tên tôi là Vân or you are 19. so do you see how this is differences your name and my name is Van 759 01:02:34,500 --> 01:02:40,559 Dot và tôi 22 tuổi nên tình trạng này sẽ xảy ra được đáp ứng và điều này cũng nên như vậy bởi vì chúng ta Dot and I am 22 so this condition should be met and so should this because we are 760 01:02:40,559 --> 01:02:44,880 sử dụng an và có nghĩa là không chỉ điều này điều kiện phải được đáp ứng nhưng cũng có điều này using an and meaning that not only this condition should be met but also this 761 01:02:44,880 --> 01:02:49,079 điều kiện thì nó nói được rồi cái này điều kiện được đáp ứng vì tên của bạn là condition then it says okay well this condition is met because your name is 762 01:02:49,079 --> 01:02:55,680 Vandal và tuổi của bạn thực ra là 20 ôi, chúng tôi có 20 ở đây nên thế là xong Vandal and your age is 20 actually oops we have 20 here so that's that's 763 01:02:55,680 --> 01:03:00,599 thú vị nên chúng tôi đã viết 22 đó là được thôi ý tôi là hãy để nó thực sự như vậy interesting so so we wrote 22 that's fine I mean let's let it actually be 764 01:03:00,599 --> 01:03:05,280 như thế này nên nó ghi tên tôi là Vandal và tuổi của tôi là 22 nên nó ghi ồ đây là like this so it says my name is Vandal and my age is 22 so it says oh this is 765 01:03:05,280 --> 01:03:10,740 chưa gặp được, vậy nên ngay khi điều này không xảy ra đã gặp và đây là một tuyên bố nó nói not met okay so as soon as this is not met and this is an and statement it says 766 01:03:10,740 --> 01:03:14,460 ồ tôi không phải thực hiện bất kỳ điều gì trong số này bây giờ vì tôi biết rằng tay trái oh I don't have to execute any of this now because I know that the left hand 767 01:03:14,460 --> 01:03:19,740 bên của toán tử và và logic toán tử không thực thi là không đúng nên tôi side of the and operator and The Logical operator is not exec is not true so I'm 768 01:03:19,740 --> 01:03:24,780 thậm chí sẽ không thực hiện điều này được rồi nếu chúng ta đặt Khối khác vào đây not even going to execute this okay then if we put an else Block in here 769 01:03:24,780 --> 01:03:33,240 sau đó chúng ta có thể nói hmm và hãy nói hmm điều đó không hiệu quả lắm, được rồi, vậy nên nếu bạn then we can say hmm and let's say hmm that didn't work so well okay so if you 770 01:03:33,240 --> 01:03:37,380 đặt dấu ngoặc đơn giữa những điều này và bạn có thể thấy rằng logic trở nên hơi put parenthesis between these and you can see that the logic becomes a little 771 01:03:37,380 --> 01:03:44,520 rõ ràng một chút và chúng ta có thể thay đổi điều này thực sự và chúng tôi nói hãy nói hoặc bit clean clear so and we can change this actually and we say let's say or 772 01:03:44,520 --> 01:03:49,680 được rồi và bây giờ đột nhiên bạn có thể thấy rằng khối mã này được thực thi okay and now all of a sudden you can see that this block of code is executed 773 01:03:49,680 --> 01:03:55,680 đơn giản vì điều này nên đúng hoặc điều này hoặc cả hai và kể từ đó simply because either this should be true or this or both of them and since 774 01:03:55,680 --> 01:04:00,299 phần này không đúng, nó ở đây này nói rằng tên của bạn là thực sự và của bạn this part is not true it comes here it says your name is for indeed and your 775 01:04:00,299 --> 01:04:06,359 tuổi là 19. bạn có nhớ H 19 tuổi và tên là Foo thì nó thực thi mã này age is 19. do you remember H was 19 and name was Foo then it executes this code 776 01:04:06,359 --> 01:04:12,599 đơn giản vì một trong những nhánh này là đúng cái này hoặc cái này hoặc cả hai và chúng tôi simply because one of these branches is true either this or this or both and we 777 01:04:12,599 --> 01:04:16,099 biết rằng điều này là đúng nên nó thực thi mã này vì vậy know that that this is true so it executes this code so 778 01:04:16,099 --> 01:04:22,680 thực ra bạn không viết mã may mắn là trong Swift thường như thế này usually you don't write code actually like this thankfully in Swift usually 779 01:04:22,680 --> 01:04:26,579 mã của bạn sẽ có ý nghĩa hơn bên trong câu lệnh if của bạn và bạn không nên your code should make more sense inside your if statements and you shouldn't 780 01:04:26,579 --> 01:04:30,839 có quá nhiều chi nhánh như thế này với ands và ORS và dấu ngoặc đơn nhưng have too many branches like this with ands and ORS and parentheses but 781 01:04:30,839 --> 01:04:34,440 đôi khi nếu bạn rất phức tạp mã nếu bạn đang làm việc với cấp độ thấp sometimes if you have very complicated code if you're working with low-level 782 01:04:34,440 --> 01:04:38,400 Ví dụ logic ở lớp Dịch vụ của bạn bạn có thể viết mã như thế này để bạn Logic for instance At Your Service layer you might write code like this so you 783 01:04:38,400 --> 01:04:44,280 nên sẵn sàng để có thể xử lý và đọc loại mã này should be ready to kind of be able to handle and read this type type of code 784 01:04:44,280 --> 01:04:47,700 nhưng tôi hoàn toàn hiểu nó là một hơi phức tạp một chút để xem xét nó nếu but I completely understand it it is a little bit complicated to look at it if 785 01:04:47,700 --> 01:04:52,079 bạn chỉ đang nhìn nó như thế này và thông thường mã như thế này là tiền tố với you're just looking at it like this and usually code like this is prefix with 786 01:04:52,079 --> 01:04:57,540 một số giải thích phổ biến tại sao chúng tôi đang làm mọi thứ theo cách chúng ta đang làm đều được some common explaining why we're doing things the way we're doing them okay 787 01:04:57,540 --> 01:05:03,119 vậy đó là điều dành cho if và else của chúng ta sân chơi trong phần tiếp theo chúng ta so that was it for our if and else playground in the next section we're 788 01:05:03,119 --> 01:05:07,200 sẽ nói về các chức năng để chúng ta có thể về cơ bản tạo một sân chơi riêng gonna talk about functions so we can create a separate playground basically 789 01:05:07,200 --> 01:05:13,319 cho các hàm sau khi làm việc với if và những tuyên bố khác chúng ta có thể tiếp tục ngay bây giờ và for functions after working with if and else statements we can go ahead now and 790 01:05:13,319 --> 01:05:17,040 làm việc với các chức năng mà chúng tôi đã thấy một số chức năng ví dụ về các hàm trong Swift trước đây work with functions we've seen a few examples of functions in Swift before 791 01:05:17,040 --> 01:05:21,059 và hy vọng bạn đã biết điều gì chức năng là vậy nên chúng ta cũng không cần phải đi and hopefully you already know what functions are so we don't have to go too 792 01:05:21,059 --> 01:05:25,740 nhiều chi tiết với các chức năng nhưng hãy tiếp tục và khám phá một số much into details with functions but let's go ahead and explore some 793 01:05:25,740 --> 01:05:30,299 những khả năng mà chúng ta có với các hàm trong Swift nên lệnh n trong xcode possibilities that we have with functions in Swift so command n in xcode 794 01:05:30,299 --> 01:05:34,200 hoặc nếu bạn đang sử dụng mã Visual Studio, tôi cũng nghĩ lệnh n và hoặc điều khiển n trên or if you're in Visual Studio code I think also command n and or control n on 795 01:05:34,200 --> 01:05:39,900 Linux và chúng tôi sẽ chỉ tìm kiếm cho sân chơi ở đây sân chơi và Linux and we are going to just search for playground in here playground and 796 01:05:39,900 --> 01:05:45,059 giả sử sân chơi trống ở đây và hãy gọi nó là chức năng và sau đó hãy let's say blank playground in here and let's call it functions and then let's 797 01:05:45,059 --> 01:05:49,920 tạo nó bên trong nhóm chính và bên trong thư mục chính được rồi và tôi nghĩ create it inside the main group and inside the main folder okay and I think 798 01:05:49,920 --> 01:05:53,940 có lẽ sẽ tốt hơn một chút nếu chúng ta thay đổi kích thước ở đây nên tôi sẽ đi would be perhaps a little bit better if we change the size in here so I'm going 799 01:05:53,940 --> 01:05:58,559 để đi đến các chủ đề trong Nửa đêm mà tôi sử dụng tôi sẽ chọn tất cả những thứ này to go to themes in Midnight which I'm using I'm going to select all of these 800 01:05:58,559 --> 01:06:04,440 và sau đó hãy thay đổi cỡ chữ có lẽ cứ nói là 36 có lẽ hoặc and then let's just change the font size perhaps to let's just say 36 perhaps or 801 01:06:04,440 --> 01:06:08,940 thậm chí 30 36 tôi nghĩ là đủ tốt vì vậy chúng tôi thấy mã tốt hơn một chút even yeah 30 36 I think is good enough so we see the code a little bit better 802 01:06:08,940 --> 01:06:13,319 được rồi vì vậy với các hàm trong Swift bạn có okay so with functions in Swift you have the 803 01:06:13,319 --> 01:06:16,980 những khả năng tương tự như bạn có trong nhiều các ngôn ngữ lập trình khác như same possibilities as you have in many other programming languages such as 804 01:06:16,980 --> 01:06:21,299 Python và phi tiêu và bản đánh máy JavaScript gần như hiện đại Python and dart and typescript JavaScript pretty much all the modern 805 01:06:21,299 --> 01:06:25,619 ngôn ngữ lập trình có một số loại cú pháp và chức năng tương tự cho programming languages have some kind of same syntax and functionality for 806 01:06:25,619 --> 01:06:30,119 chức năng vì vậy chúng ta hãy xem xét một vài ví dụ vì vậy giả sử chúng tôi nhập functions so let's have a look at a few examples so let's say we import 807 01:06:30,119 --> 01:06:34,200 Sự thành lập Tôi sẽ loại bỏ phần đó cho Foundation I'm gonna get rid of that part to the 808 01:06:34,200 --> 01:06:41,039 left hoặc Explorer để chúng tôi có thể tạo các hàm trong Swift với cú pháp func left or Explorer so we can create functions in Swift with the func syntax 809 01:06:41,039 --> 01:06:45,180 hoặc một từ khóa và sau đó là tên của chức năng và nó phải là trường hợp lạc đà or a keyword and then the name of the function and it should be camel case 810 01:06:45,180 --> 01:06:49,020 có nghĩa là từ đầu tiên của tên hàm tất cả phải là chữ thường meaning that the first word of the function name should all be lowercase on 811 01:06:49,020 --> 01:06:54,119 tất cả các từ tiếp theo bên trong tên hàm nên có hoặc tên đầu tiên của chúng all the subsequent words inside the function name should have or their first 812 01:06:54,119 --> 01:06:58,920 chữ cái viết hoa và tất cả những chữ khác các chữ cái ở dạng chữ thường nên đây là một letter as uppercase and all the other letters as lowercase so here is an 813 01:06:58,920 --> 01:07:02,579 ví dụ về một hàm không có đối số và nó không có giá trị trả về nên example of a function that takes no arguments and it has no return value so 814 01:07:02,579 --> 01:07:08,640 hãy nói rằng không có đối số và không có trở lại giá trị bạn có thể thấy tất cả nếu lần đầu tiên let's say no arguments and no return value you can see all the if the first 815 01:07:08,640 --> 01:07:13,680 từ có tất cả các chữ cái là chữ thường và tất cả các từ khác đều có chữ đầu tiên word has all its letters as lowercase and all the other words have their first 816 01:07:13,680 --> 01:07:18,119 các chữ cái viết hoa theo sau từ đầu tiên được rồi letters as uppercase that follow the first word okay 817 01:07:18,119 --> 01:07:23,039 sau đó chúng tôi đặt dấu ngoặc đơn vào đây và chúng ta có thể đặt các lập luận của mình vào giữa then we put uh parenthesis in here and we can put our arguments in between the 818 01:07:23,039 --> 01:07:26,579 dấu ngoặc đơn nhưng chức năng này không có bất kỳ tranh luận nào thì chúng ta sẽ làm xoăn parenthesis but this function doesn't have any arguments then we do curly 819 01:07:26,579 --> 01:07:31,140 dấu ngoặc và sau đó bên trong đường cong dấu ngoặc là phần thân của hàm của bạn brackets and then inside the curly brackets is the body of your function 820 01:07:31,140 --> 01:07:38,099 và ở đây chúng ta sẽ nói rằng tôi không tôi không biết mình đang làm gì có ổn không and here we're just going to say I don't have I don't know what I'm doing okay 821 01:07:38,099 --> 01:07:41,640 và cách chúng tôi viết những điều này ở sân chơi có một chút đặc biệt and the way that we write these things in playground is a little bit special 822 01:07:41,640 --> 01:07:45,420 bởi vì trong sân chơi Swift dù thế nào đi nữa bạn gõ như chuỗi thực sự sẽ là because in Swift playgrounds whatever you type as the string will actually be 823 01:07:45,420 --> 01:07:50,039 được in bên trong bản xem trước của sân chơi tuy nhiên đây không phải là cách bạn sẽ làm printed inside the playground's preview however this is not how you would 824 01:07:50,039 --> 01:07:54,240 thực sự viết Swift Code để bạn có thể có lẽ chỉ cần đưa ra một tuyên bố in actually write Swift Code so you would probably just issue a print statement 825 01:07:54,240 --> 01:07:59,460 được thôi nhưng ở sân chơi thì điều này khiến hợp lý vậy hãy cứ tự động chạy okay but in playgrounds this does make sense so let's just do automatically run 826 01:07:59,460 --> 01:08:03,180 ở đây để mã của chúng tôi được thực thi tự động mà không cần chúng tôi phải làm in here so our code gets executed automatically without us having to do 827 01:08:03,180 --> 01:08:06,720 bất cứ điều gì và bạn có thể thấy không có gì là được in ở đây đơn giản vì chúng tôi anything and you can see nothing is being printed here simply because we're 828 01:08:06,720 --> 01:08:11,819 không gọi hoặc gọi chức năng của chúng tôi bây giờ quá trình gọi một hàm là not calling or invoking our function now the process of invoking a function is 829 01:08:11,819 --> 01:08:16,319 chỉ để nói với Swift rằng bạn muốn mã bên trong hàm này là just to tell to tell Swift that you want the code inside this function to be 830 01:08:16,319 --> 01:08:21,719 được thực hiện và cách để làm điều đó chỉ là bạn sử dụng tên hàm không có đối số executed and the way to do that is just you use the function name no arguments 831 01:08:21,719 --> 01:08:26,279 và sau đó với dấu ngoặc đơn và bất kỳ đối số mà hàm mong đợi and then with the parenthesis and any arguments that the function expects 832 01:08:26,279 --> 01:08:29,699 may mắn thay bây giờ trong ngoặc đơn hàm này không có bất kỳ đối số nào within the parenthesis now thankfully this function doesn't have any arguments 833 01:08:29,699 --> 01:08:33,960 vì vậy chúng ta không cần phải vượt qua bất kỳ đối số nào trong dấu ngoặc đơn và bạn so we don't have to pass any arguments within the parenthesis either and you 834 01:08:33,960 --> 01:08:40,679 có thể thấy giá trị sau đó được in vào bảng điều khiển sân chơi ở đây được rồi bây giờ chúng ta can see the value is then printed to our playground console in here okay now we 835 01:08:40,679 --> 01:08:45,179 cũng có thể có những chức năng có đối số vì vậy hãy tạo một hàm can also have functions that have arguments so let's create a function 836 01:08:45,179 --> 01:08:50,339 nhận bất kỳ giá trị nguyên nào và cộng giá trị của 2 cho nó nhưng đặc biệt này that takes any integer value and adds the value of 2 to it but this particular 837 01:08:50,339 --> 01:08:53,819 chức năng sẽ không có bất kỳ lợi nhuận nào giá trị một lần nữa vì vậy chúng ta sẽ có function is not going to have any return value again so we're just going to have 838 01:08:53,819 --> 01:08:59,580 hãy xem cách truyền đối số cho một chức năng vì vậy hãy nói func cộng với hai vì vậy a look at how to pass arguments to a function so let's say func plus two so 839 01:08:59,580 --> 01:09:04,199 như thế này và sau đó chúng tôi lấy một giá trị và bạn có thể thấy đây là cách bạn chỉ định một like this and then we take a value and you can see this is how you specify an 840 01:09:04,199 --> 01:09:08,640 đối số cho một hàm trong Swift bạn chỉ cần gõ tên của đối số và sau đó bạn argument to a function in Swift you just type name of the argument and then you 841 01:09:08,640 --> 01:09:12,839 gõ kiểu dữ liệu và cũng có một cách khác để làm điều này và tôi sẽ type the data type and also there's another way of doing this and I'll 842 01:09:12,839 --> 01:09:17,580 giải thích nó sau và bạn có thể có hai nhãn cho một biến một bên ngoài explain it later and you can have two labels for a variable one an external 843 01:09:17,580 --> 01:09:20,339 nhãn và nhãn nội bộ thứ gì đó label and an internal label which is something 844 01:09:20,339 --> 01:09:25,199 khá độc đáo với Swift bạn có thể có nó trong một số ngôn ngữ khác nhưng không hẳn như vậy quite unique to Swift you can have it in some other languages but not in all so 845 01:09:25,199 --> 01:09:28,920 đây là một ví dụ về một hàm bên trong tạo ra một biến mới, hãy here's an example of a function that internally creates a new variable let's 846 01:09:28,920 --> 01:09:34,020 gọi nó là giá trị mới và sau đó lấy giá trị đó giá trị và thêm 2 vào nó bằng một đơn vị call it new value and then takes that value and adds a 2 to it with a unary 847 01:09:34,020 --> 01:09:38,160 với toán tử trung tố nhị phân như chúng ta đã Đã từng nhìn thấy trước đây with a binary infix operator as we've seen before 848 01:09:38,160 --> 01:09:42,000 nhưng bạn có thể thấy rằng nó không trở lại bất cứ điều gì cũng được và chúng ta có thể nói cộng hai but you can see that it doesn't return anything okay and we can say plus two 849 01:09:42,000 --> 01:09:46,199 và sau đó chúng ta có thể chuyển giá trị 30 vào ở đây và bạn có thể thấy giá trị mới sẽ là and then we can pass the value of 30 in here and you can see new value will be 850 01:09:46,199 --> 01:09:52,199 bằng 32 trong hàm này tất cả đúng vậy về cơ bản đó là cách bạn có thể equal to 32 within this function all right so that's how you can basically 851 01:09:52,199 --> 01:09:56,880 truyền một biến cho hàm bằng cách sử dụng một lý lẽ pass a variable to a function using an argument 852 01:09:56,880 --> 01:10:01,140 bạn có thể có các hàm trả về cũng có giá trị nên họ thực hiện một số you can have functions that return values as well so they do some 853 01:10:01,140 --> 01:10:05,760 tính toán và sau đó chúng trả về một giá trị và cách để làm điều đó là sử dụng cái này calculation and then they return a value and the way to do that is to use this 854 01:10:05,760 --> 01:10:10,860 cú pháp cụ thể như tôi sẽ chỉ cho bạn bây giờ giả sử mới cộng 2 và sau đó chúng ta lấy particular syntax as I'll show you now let's say new plus 2 and then we take a 855 01:10:10,860 --> 01:10:14,760 giá trị của kiểu số nguyên và chúng tôi trả về một giá trị ở đây và sau đó chúng ta chỉ có thể nói value of type integer and we return a value in here and then we can just say 856 01:10:14,760 --> 01:10:20,760 chúng tôi trả lại giá trị của giá trị về cơ bản cộng với hai và lợi nhuận we return the value of value basically plus two and the return 857 01:10:20,760 --> 01:10:25,620 câu lệnh trong các hàm đơn giản này chỉ có một dòng mã là statements in these simple functions that just have one line of code is 858 01:10:25,620 --> 01:10:30,060 tùy chọn đây là thứ mà Swift đã lấy đi từ rỉ sét tuy nhiên rỉ sét lại có optional this is something that Swift has taken from rust however rust takes 859 01:10:30,060 --> 01:10:34,320 nó lên một tầm cao mới trong sự rỉ sét đó thậm chí còn cho phép bạn gõ thêm một số it to an entirely new level in that rust allows even for you to type some more 860 01:10:34,320 --> 01:10:39,060 mã ở đây và sau đó là câu lệnh cuối cùng bên trong hàm không có code in here and then the last statement inside the function that doesn't have a 861 01:10:39,060 --> 01:10:44,699 dấu chấm phẩy sẽ được trả về tuy nhiên Swift không có khả năng đó vì vậy semicolon will be returned however Swift doesn't have that ability so because 862 01:10:44,699 --> 01:10:50,760 dấu chấm phẩy là tùy chọn trong Swift vì vậy nếu bạn không muốn có giá trị trả về trong semicolons are optional in Swift so if you don't want to have a return value in 863 01:10:50,760 --> 01:10:54,780 ở đây nếu bạn không muốn gõ trả về cú pháp ở đây hoặc từ khóa bạn đang here if you don't want to type the return syntax in here or keyword you're 864 01:10:54,780 --> 01:10:59,219 được chào đón nhiều nhất để làm điều đó mã hiện đại thực sự phát ra lợi nhuận vì vậy nếu more than welcome to do that the most modern code actually emits return so if 865 01:10:59,219 --> 01:11:04,460 bạn thấy một tuyên bố như thế này hàm được thiết lập để trả về câu lệnh này you see a statement like this this function is set to return this statement 866 01:11:04,460 --> 01:11:09,719 ngầm được rồi và cách gọi đó là bạn có thể nói mới cộng hai và implicitly all right and the way to call it is that you can say new plus two and 867 01:11:09,719 --> 01:11:13,980 sau đó bạn chuyển giá trị 30 và bạn có thể thấy giá trị 32 sẽ được trả về then you pass the value of 30 and you can see the value of 32 will be returned 868 01:11:13,980 --> 01:11:19,380 từ chức năng này được rồi bây giờ bạn cũng có thể có các chức năng với from this function okay now you can also have functions with 869 01:11:19,380 --> 01:11:25,140 nhiều đối số vì vậy hãy nói func tùy chỉnh THÊM để chúng tôi có chức năng thêm mới multiple arguments so let's say func custom ADD so we have a new add function 870 01:11:25,140 --> 01:11:30,540 ở đây được rồi và chúng tôi lấy hai biến vì vậy hãy nói giá trị một int và giá trị hai in here okay and we take two variables so let's say value one int and value two 871 01:11:30,540 --> 01:11:37,380 int được rồi và sau đó chúng tôi cũng trả về một INT nên những gì chúng tôi trả lại là giá trị One Plus int all right and then we return also an INT so what we return is value One Plus 872 01:11:37,380 --> 01:11:41,460 giá trị hai được rồi vì vậy chúng tôi lấy hai đối số có giá trị một cụ thể là và giá trị hai value two all right so we take two arguments value one namely and value two 873 01:11:41,460 --> 01:11:46,199 chúng tôi thêm chúng và chúng tôi chỉ trả lại chúng như một phần của khai báo hàm của chúng tôi we add them and we just return them as part of our function declaration all 874 01:11:46,199 --> 01:11:50,040 Phải sau đó chúng ta có thể gán giá trị trả về của right then we can assign the return value of 875 01:11:50,040 --> 01:11:55,199 quảng cáo tùy chỉnh này thành một biến, vì vậy hãy nói hãy tùy chỉnh THÊM nó this custom ad to a variable so let's say let custom ADD it 876 01:11:55,199 --> 01:12:00,179 bằng để thực hiện chức năng của quảng cáo tùy chỉnh và đối với Giá trị 1, chúng tôi chuyển is equal to execute the function of custom ad and for Value 1 we pass the 877 01:12:00,179 --> 01:12:05,699 giá trị 210 và đối với giá trị thứ hai, chúng tôi chuyển giá trị 20 và bạn có thể thấy value of 210 and for the second value we pass the value of 20 and you can see the 878 01:12:05,699 --> 01:12:10,080 kết quả là giá trị 30. vì vậy hàm này đang được thực thi và nó được trả về result is value of 30. so this function is being executed and it's returned 879 01:12:10,080 --> 01:12:13,560 giá trị đang được gán cho biến này ở phía bên trái của bài tập value is being assigned to this variable to the left hand side of the assignment 880 01:12:13,560 --> 01:12:19,739 được rồi, bây giờ bạn cũng có thể có chức năng không có cái này bên ngoài operator okay now you can also have functions that do not have this outside 881 01:12:19,739 --> 01:12:24,719 dán nhãn như nó được gọi như vậy tại thời điểm hàm này có hai đối số label as as it is called so at the moment this function has two arguments 882 01:12:24,719 --> 01:12:29,940 và họ chỉ có một nhãn nhãn này được sử dụng bên ngoài như bạn có thể thấy ở and they only have one label this label is used externally as you can see at the 883 01:12:29,940 --> 01:12:35,100 trang web cuộc gọi và cả nội bộ bên trong tuy nhiên các hàm cũng có thể call site and also internally inside the function however functions can also 884 01:12:35,100 --> 01:12:40,800 xác định cách các nhãn này được tạo ra mọi đối số có thể có hai nhãn xin lỗi determine how these labels are created every argument can have two label sorry 885 01:12:40,800 --> 01:12:48,659 hai nhãn bên ngoài và bên trong được rồi bạn có thể thấy điều đó bên trong two labels external and internal okay so you can see that then internally inside 886 01:12:48,659 --> 01:12:52,440 chức năng này nhãn này không có sẵn vì vậy nếu bạn gõ bên ngoài ở đó this function this label is not available so if you type external there 887 01:12:52,440 --> 01:12:55,560 không có gì có sẵn nhưng nếu bạn gõ nội bộ thì nó có sẵn cho bạn is nothing available but if you type internal then it is available to you 888 01:12:55,560 --> 01:13:01,020 được rồi vậy chúng ta hãy quay lại đây và hãy xem một ví dụ về hàm okay so and let's go back in here and have a look at an example of a function 889 01:13:01,020 --> 01:13:06,480 không có bất kỳ nhãn bên ngoài nào được rồi vì lý lẽ của nó nên hãy that doesn't have any external labels all right so for its arguments so let's 890 01:13:06,480 --> 01:13:11,760 nói func tùy chỉnh trừ đi được rồi và nó có hai đối số và chúng ta hãy gọi say func custom minus all right and it has two arguments and let's just call 891 01:13:11,760 --> 01:13:16,620 họ bên tay trái và sau đó là tay phải bên và chúng tôi cũng trả về một số nguyên them left hand side and then right hand side and we return an integer as well 892 01:13:16,620 --> 01:13:20,159 được rồi ôi và sau đó chúng ta nói phía bên trái okay oops and then we say left hand side 893 01:13:20,159 --> 01:13:25,739 trừ đi bên tay phải bây giờ nếu bạn gọi chức năng này vẫn như cũ minus right hand side now if you call this function just the way it is then 894 01:13:25,739 --> 01:13:30,719 bạn có thể viết như thế này được không trừ nó you can you can write like this custom subtract it 895 01:13:30,719 --> 01:13:36,179 và sau đó chúng tôi nói bằng với dấu trừ tùy chỉnh và sau đó hãy nói, hãy nói and then we say is equal to custom minus and then let's let's say let's say the 896 01:13:36,179 --> 01:13:42,300 giá trị 20 và giá trị 10 ở đây được rồi và bạn có thể dễ dàng thấy điều đó tại value of 20 and the value of 10 in here okay and you can see then easily that at 897 01:13:42,300 --> 01:13:48,300 trang web cuộc gọi chúng tôi phải vượt qua những điều này Tuy nhiên, tên đối số LHS và rhs nếu the call site we have to pass these argument names LHS and rhs however if 898 01:13:48,300 --> 01:13:52,140 bạn không muốn làm điều đó nếu bạn không muốn chuyển một tên đối số, bạn có thể you don't want to do that if you don't want to pass a an argument name you can 899 01:13:52,140 --> 01:13:56,400 chỉ cần nói dấu trừ tùy chỉnh và sau đó bạn muốn nói 20 và 10 như thế thì bạn có just say custom minus and then you want to say 20 and 10 like that then you have 900 01:13:56,400 --> 01:14:01,320 để đảm bảo rằng Swift có được tên bên ngoài là dấu gạch dưới như thế này to make sure that Swift gets the external name as underscore like this so 901 01:14:01,320 --> 01:14:05,280 gạch dưới đơn giản có nghĩa là cuộc gọi trang web nơi bạn đang gọi chức năng này underscore simply means that the a call site where you're calling this function 902 01:14:05,280 --> 01:14:09,840 từ không nên có tên đối số nên bạn có thể thấy bây giờ bạn phải xóa LHS from shouldn't have argument names so you can see now you have to remove LHS 903 01:14:09,840 --> 01:14:13,620 và rhs và sau đó mã của bạn sẽ hoạt động như hy vọng and rhs and then your code will work as expected 904 01:14:13,620 --> 01:14:19,860 được rồi, về cơ bản đó là cách bạn có thể bỏ qua tên đối số bên ngoài và chỉ okay so that's how you can basically ignore external argument names and just 905 01:14:19,860 --> 01:14:25,560 hãy nhớ rằng lần đầu tiên, ừ, lần đầu tiên một phần tên của đối số có thể là của nó keep in mind that the first uh the first part of the argument's name can be its 906 01:14:25,560 --> 01:14:28,880 tên bên ngoài và sau đó nếu bạn đặt một không gian và sau đó là một không gian khác external name and then if you put a space and then another 907 01:14:28,880 --> 01:14:34,560 về cơ bản là từ hoặc câu hy vọng là không một câu nhưng nó sẽ là một vài từ basically word or sentence hopefully not a sentence but a few words it will be 908 01:14:34,560 --> 01:14:39,600 tên nội bộ của đối số đó được rồi và nếu bạn không có cái tên duy nhất đó the internal name of that argument okay and if you don't have that the only name 909 01:14:39,600 --> 01:14:44,179 bạn có ở đây sẽ có sẵn bên ngoài và bên trong đều ổn you have in here will be available externally and internally all right 910 01:14:44,179 --> 01:14:48,960 tốt vậy ừm nếu bây giờ bạn đang trong sạch good so um if you are now if you're in pure 911 01:14:48,960 --> 01:14:52,860 Swift bạn có thể thấy ở đây chúng tôi đang ở khoảnh khắc gọi đây là một chức năng như Swift you can see in here we're at the moment calling this a function like 912 01:14:52,860 --> 01:14:57,360 điểm trừ tùy chỉnh nhưng nếu bạn sử dụng Swift thuần túy có nghĩa là bạn không ở trong custom minus but if you're in pure Swift meaning that you're not inside a 913 01:14:57,360 --> 01:15:02,219 sân chơi nếu bạn gọi một hàm có giá trị trả về nên giả sử chi phí playground if you call a function that has a return value so let's say cost 914 01:15:02,219 --> 01:15:07,140 họ thêm và sau đó bạn nói giá trị một là 20 giá trị 2 them add and then you say value one is 20 value 2 915 01:15:07,140 --> 01:15:12,120 là 30. trong một sân chơi bạn chỉ cần nhận được giá trị trả về và giá trị trả về của is 30. in a playground you just get the return value and the return value of 916 01:15:12,120 --> 01:15:16,560 chức năng này sẽ được hiển thị ở đây tuy nhiên nếu bạn đang ở ngang hàng nghĩa là Swift this function will be displayed here however if you're in peer Swift meaning 917 01:15:16,560 --> 01:15:21,239 rằng bạn không ở trong sân chơi làm điều này thực sự sẽ mang lại cho bạn một that you're not inside a playground then doing this will actually give you a 918 01:15:21,239 --> 01:15:25,080 cảnh báo cho bạn biết rằng bạn đang gọi một chức năng mà không tiêu thụ kết quả của nó warning telling you that you're calling a function without consuming its result 919 01:15:25,080 --> 01:15:29,520 lý do chúng ta không gặp nhau vào sáng hôm đó trong một sân chơi đó có phải là sân chơi không the reason we're not seeing that morning in a playground is that playgrounds 920 01:15:29,520 --> 01:15:34,679 tiêu thụ kết quả của tất cả các chức năng ngầm và gõ chúng ra ở đây trong consume the result of all functions implicitly and and type them out here in 921 01:15:34,679 --> 01:15:39,360 bản xem trước nhưng bên trong Mã Swift thuần túy khi bạn đang viết như mã iOS hoặc Mac the preview but inside pure Swift Code when you're writing like iOS code or Mac 922 01:15:39,360 --> 01:15:44,340 Mã hệ điều hành hoặc xem hệ điều hành bất cứ điều gì và bạn về cơ bản bạn không có sân chơi ở OS code or watch OS whatever and you're basically you don't have a playground in 923 01:15:44,340 --> 01:15:47,940 những mã đó là Mã Swift thuần túy nên bạn cần phải tiêu thụ những giá trị này có nghĩa là those codes it's pure Swift Code so you need to consume these values meaning 924 01:15:47,940 --> 01:15:51,300 mà bạn phải gán chúng cho một cái gì đó ổn như thế và sau đó bạn that you have to assign them to something okay like that and then you 925 01:15:51,300 --> 01:15:55,620 cũng cần phải tiêu thụ thứ này bằng cách nào đó ngay cả khi bạn gõ mã như thế này thì nó need to also consume this somehow so even if you type code like this so it 926 01:15:55,620 --> 01:16:00,239 sẽ phàn nàn rằng này bạn chỉ định cái này để thêm nó nhưng bạn thì không will complain saying that hey you're assigning this to add it but you're not 927 01:16:00,239 --> 01:16:05,520 sử dụng thêm vào bất cứ đâu vậy vấn đề là gì thực hiện chức năng này gọi được rồi nên using added anywhere so what's the point of doing this function call all right so 928 01:16:05,520 --> 01:16:10,620 nếu bạn muốn viết một hàm trong Swift tuy nhiên điều đó tạo ra một giá trị if you want to write a function in Swift that does produce a value however the 929 01:16:10,620 --> 01:16:14,699 người hoặc địa điểm gọi nơi bạn đang ở gọi hàm đó không person or the call site where you're calling that function doesn't 930 01:16:14,699 --> 01:16:19,500 nhất thiết phải tiêu thụ giá trị đó bạn có thể đánh dấu chức năng đó là necessarily have to consume that value you can mark that function as 931 01:16:19,500 --> 01:16:24,179 kết quả có thể loại bỏ được và tôi sẽ chỉ cho bạn cách để làm điều đó, hãy tiếp tục và tạo discardable result and I'll show you how to do that so let's go ahead and create 932 01:16:24,179 --> 01:16:29,760 chức năng THÊM tùy chỉnh của tôi ở đây vì vậy chúng tôi nói theo phong tục của tôi được rồi và sau đó chúng ta có a my custom ADD function in here so we say my custom at okay and then we have 933 01:16:29,760 --> 01:16:33,780 hai đối số ở đây đó là bên ngoài không có tên nhưng bên trong two arguments in here that are externally not named but internally 934 01:16:33,780 --> 01:16:40,620 chúng được gọi là LHS như ở phía bên trái và sau đó chúng ta có rhs ở đây được rồi và chúng ta they're called LHS as in left hand side and then we have rhs in here okay and we 935 01:16:40,620 --> 01:16:45,420 cũng trả về số nguyên và chúng ta nói LHS cộng với rhs vì vậy nếu bạn muốn chức năng này return integer as well and we say LHS plus rhs so if you want this function to 936 01:16:45,420 --> 01:16:49,560 có thể tạo ra số nguyên nhưng cuộc gọi bên cạnh màu sắc của chức năng này không be able to produce integer but the call side the color of this function doesn't 937 01:16:49,560 --> 01:16:53,960 phải tiêu thụ số nguyên đó bạn cần đánh dấu chức năng này là kết quả có thể loại bỏ have to consume that integer you need to mark this function as discardable result 938 01:16:53,960 --> 01:16:58,440 làm điều này ở sân chơi không có nghĩa là không có sự khác biệt nào cả bởi vì như tôi doing this in a playground doesn't make any difference at all because as I 939 01:16:58,440 --> 01:17:03,060 sân chơi được đề cập tiêu thụ kết quả Tuy nhiên, tất cả các chức năng đều ngầm nếu mentioned playgrounds consume the result of all functions implicitly however if 940 01:17:03,060 --> 01:17:07,560 bạn đang sử dụng Swift thuần túy, điều này sẽ tạo nên một rất có ý nghĩa và thành thật mà nói với bạn you're in pure Swift this will make a lot of sense and to be honest with you 941 01:17:07,560 --> 01:17:11,760 chúng ta thực sự có thể xem cái này nghĩa là bây giờ tôi đang ứng biến một chút we can actually have a look at this I mean now I'm improvising a little bit 942 01:17:11,760 --> 01:17:15,300 Tôi sẽ thoát khỏi kịch bản nhưng hãy để tôi chỉ cần tạo một dự án iOS đơn giản ở đây I'm just going off the script but let me just create a simple iOS project in here 943 01:17:15,300 --> 01:17:19,739 và giả sử ứng dụng của tôi và sau đó chúng ta sẽ lưu nó vào and let's say my app and then we're just gonna save it on 944 01:17:19,739 --> 01:17:23,219 máy tính để bàn thì ổn thôi, tôi không thực sự quan tâm nơi nó được lưu vào lúc này vì vậy hãy desktop it's fine I don't really care where it is saved at the moment so let's 945 01:17:23,219 --> 01:17:27,120 chỉ cần lưu nó và để tôi chỉ cho bạn xem nó trông như thế nào just save it and let me just show you how this looks 946 01:17:27,120 --> 01:17:31,739 bên trong một ví dụ Swift UI ứng dụng vì vậy nếu bạn truy cập ứng dụng của chúng tôi trong inside a for instance Swift UI application so if you go into our app in 947 01:17:31,739 --> 01:17:36,020 ở đây và nói ừm chúng ta nên làm gì ở đây hãy nói xem here and say um what should we do in here let's say 948 01:17:36,020 --> 01:17:41,040 có lẽ chúng ta có một nhóm cửa sổ ở đây chúng ta hãy đi tới nội dung Xem perhaps we have a window group in here let's go to content View 949 01:17:41,040 --> 01:17:45,120 và bây giờ chúng tôi có một ứng dụng giao diện người dùng nhanh mặc dù vậy sẽ tốt hơn nếu and now we have a swift UI application though so it would have been better if 950 01:17:45,120 --> 01:17:49,739 chúng tôi thực sự đã tạo ra một ừm hãy tạo một hồ sơ ở đây Swift we actually created a um let's just create a filing here Swift 951 01:17:49,739 --> 01:17:56,820 tập tin hãy nói rằng dịch vụ của tôi được rồi và ở đây hãy nói rằng chúng ta có file let's say my service okay and in here let's just say that we have 952 01:17:56,820 --> 01:18:01,140 Một chúng ta nên làm gì hãy nói uh struct a what should we do let's say uh struct 953 01:18:01,140 --> 01:18:05,699 người ổn và sau đó chúng tôi tạo một hàm ở đây person okay and then we create a function in here 954 01:18:05,699 --> 01:18:10,620 giống như chúng ta đang học bây giờ chúng ta nói có được H và đây thực sự không phải là cách chúng tôi viết just like we're learning now we say get H and this is not really how we write 955 01:18:10,620 --> 01:18:14,760 dù sao thì mã cũng bình thường nhưng đây là dành cho mục đích trình diễn và sau đó chúng tôi normal code anyways but this is for the purpose of demonstration and then we 956 01:18:14,760 --> 01:18:18,840 có một chức năng khác được gọi là làm một cái gì đó và sau đó chúng ta nói độ dài tuổi là have another function that's called do something and then we say length age is 957 01:18:18,840 --> 01:18:23,340 nhận được H vì vậy chúng tôi gọi hàm đó ngay bây giờ nếu chúng tôi để lại mã này như thế này để tôi chỉ get H so we call that function now if we leave this code like this let me just 958 01:18:23,340 --> 01:18:27,300 thực sự thay đổi điều này thành vâng, điều đó ổn thôi nếu bạn cố gắng biên dịch mã này, bạn có thể actually change this to yeah that's fine if you try to compile this code you can 959 01:18:27,300 --> 01:18:30,600 thấy rằng bây giờ chúng ta đang nhận được khởi tạo tuổi giá trị bất biến see that now we're getting initialization of immutable value age 960 01:18:30,600 --> 01:18:35,460 không được sử dụng hoặc một cái gì đó không bao giờ được sử dụng được thôi và bạn ngay cả khi bạn viết mã của mình was not used or something was never used okay and you even if you write your code 961 01:18:35,460 --> 01:18:40,080 như thế này bạn sẽ nhận được một cảnh báo tương tự kết quả của cuộc gọi để nhận được sự ủng hộ của bạn vì vậy like this you will get a warning same result of call to get ages on you so 962 01:18:40,080 --> 01:18:42,900 đây là lời cảnh báo rằng tôi vừa mới nói về bên trong một sân chơi bạn this is the warning that I was just talking about inside a playground you 963 01:18:42,900 --> 01:18:46,440 không nhận được những Cảnh báo này nhưng bên trong Mã Swift thuần túy bạn nhận được những Cảnh báo này don't get These Warnings but inside a pure Swift Code you get These Warnings 964 01:18:46,440 --> 01:18:50,880 vì vậy cách khắc phục là thêm tiền tố này với kết quả có thể loại bỏ và sau đó biên dịch so the way to fix that is to prefix this with discardable result and then compile 965 01:18:50,880 --> 01:18:55,219 mã của bạn bạn có thể thấy và nó đang hoạt động tuy nhiên như mong đợi nếu bạn chỉ định cái này your code you can see then it's working as expected however if you assign this 966 01:18:55,219 --> 01:19:00,239 đến một biến bạn sẽ nhận được cảnh báo dù sao đi nữa vì bạn đang gán nó cho một to a variable you will get the warning anyways because you're assigning it to a 967 01:19:00,239 --> 01:19:03,600 biến mà sau này bạn không sử dụng nên kết quả có thể loại bỏ này không khắc phục được điều này variable that you're not using later so this discardable result doesn't fix this 968 01:19:03,600 --> 01:19:07,620 tuy nhiên vấn đề này khắc phục được vấn đề bạn gọi hàm này mà không có this issue however it fixes the issue of you calling this function without 969 01:19:07,620 --> 01:19:12,540 gán biến của nó cho bất kỳ giá trị nào xin lỗi mà không gán giá trị của nó cho bất kỳ assigning its variable to any values sorry without assigning its value to any 970 01:19:12,540 --> 01:19:15,600 biến được rồi tốt bạn không cần phải tạo ra cái này variables okay good you didn't have to create this 971 01:19:15,600 --> 01:19:19,860 dự án ý tôi là đây chỉ là một thử nghiệm được thôi để tôi có thể chứng minh điều tôi muốn nói project I mean this was just a test okay so that I can demonstrate what I meant 972 01:19:19,860 --> 01:19:25,380 trong trường hợp này bây giờ chúng ta có rằng chúng ta chỉ cần nhập quảng cáo tùy chỉnh của tôi và sau đó chúng tôi in this case now that we have that we can just type my custom ad and then we 973 01:19:25,380 --> 01:19:30,260 chỉ có thể nói giá trị của 20 và 30 ở đây mà không cần phải lo lắng về can just say say the value of 20 and 30 in here without having to worry about 974 01:19:30,260 --> 01:19:34,380 tiêu thụ kết quả của chức năng này bây giờ bạn có thể đang nghĩ nhưng tại sao consuming the result of this function now you you may be thinking but why 975 01:19:34,380 --> 01:19:38,460 bạn có thể viết một hàm như thế không à, một số chức năng chẳng hạn như trong would you write a function like that well some functions for instance in 976 01:19:38,460 --> 01:19:42,540 các lớp dịch vụ bên trong một ứng dụng có thể thực hiện một số công việc phức tạp và họ có thể service layers inside an application may do some complicated work and they may 977 01:19:42,540 --> 01:19:46,800 tạo ra một giá trị Boolean cho biết tuy nhiên nó có thành công hay không produce a Boolean value indicating whether it was successful or not however 978 01:19:46,800 --> 01:19:50,219 không phải lúc nào bạn cũng thực sự quan tâm về giá trị Boolean đó và bạn có thể it's not always that you actually care about that Boolean value and you can 979 01:19:50,219 --> 01:19:54,120 gọi hàm đó mà không quan tâm đến kết quả của nó trong trường hợp đó bạn có thể thêm tiền tố call that function without caring about its result in that case you can prefix 980 01:19:54,120 --> 01:19:58,080 khai báo hàm với một kết quả có thể loại bỏ như tôi đã chỉ cho bạn đúng the function declaration with a discardable result as I showed you right 981 01:19:58,080 --> 01:20:04,440 ở đây được rồi bây giờ các chức năng cũng có thể chứa chức năng riêng của họ nên đây là một cái gì đó here okay now functions can also contain their own functions so this is something 982 01:20:04,440 --> 01:20:08,100 không có nhiều ngôn ngữ chương trình hỗ trợ hỗ trợ phi tiêu chẳng hạn vậy thì bạn that not many program languages support darts for instance support so then you 983 01:20:08,100 --> 01:20:10,739 cũng có thể có một cái gì đó như thế trong rỉ sét cũng vậy can also have something like that in Rust as well 984 01:20:10,739 --> 01:20:16,440 vì vậy hãy xem xét điều đó để chúng tôi nói funk làm điều gì đó phức tạp với một so let's have a look at that so we say funk do something complicated with a 985 01:20:16,440 --> 01:20:21,960 giá trị và bạn có thể thấy chiều rộng là nhãn và giá trị đối số bên ngoài là value and you can see width is the external argument label and value is the 986 01:20:21,960 --> 01:20:25,260 nhãn đối số nội bộ ở đây được rồi và hàm này chúng ta có thể thấy trả về một internal argument label in here okay and this function we can see returns an 987 01:20:25,260 --> 01:20:31,140 số nguyên hãy chia nhỏ tham số này như thế này và sau đó ở đây chúng tôi nói chúng tôi integer let's break this parameter down like this and then in here we say we 988 01:20:31,140 --> 01:20:35,219 có một chức năng khác bên trong cái này thực ra logic có ổn nên chúng tôi nói have another function inside this that actually does the logic okay so we say 989 01:20:35,219 --> 01:20:39,900 logic chính với một giá trị và trả về INT và trong main logic with a value and returns an INT and in 990 01:20:39,900 --> 01:20:43,800 ở đây chúng tôi chỉ nói Value Plus 2 được rồi chúng tôi thực sự không làm gì cả here we just say Value Plus 2 okay so we're not really doing anything 991 01:20:43,800 --> 01:20:48,239 phức tạp, chúng tôi chỉ cộng giá trị với 2. tuy nhiên chức năng này làm được complicated we're just plusing the value with 2. however this function do 992 01:20:48,239 --> 01:20:52,020 cái gì đó phức tạp lại chứa đựng cái khác chức năng thực hiện logic thực tế và something complicated contains another function that does the actual logic and 993 01:20:52,020 --> 01:20:55,739 chức năng này sau đó có thể gọi nó hoạt động nội bộ nhưng không có ai khác trong this function then can call this function internally but no one else in 994 01:20:55,739 --> 01:21:00,179 toàn bộ ứng dụng có thể gọi đây chức năng này chức năng này chỉ có sẵn the entire application can call this function this function is only available 995 01:21:00,179 --> 01:21:05,340 vào chức năng này bởi vì nó được viết bên trong nó được rồi, điều chúng ta có thể làm là to this function because it is written inside it okay then what we can do is 996 01:21:05,340 --> 01:21:11,340 nói trả về logic chính mà chúng tôi gọi đó chức năng chúng tôi nói Value Plus ba sau đó trong say return the main logic we call that function we say Value Plus three then in 997 01:21:11,340 --> 01:21:14,760 ở đây chúng ta có thể tiếp tục và nói làm một cái gì đó phức tạp với giá trị của here we can go ahead and say do something complicated with the value of 998 01:21:14,760 --> 01:21:18,780 30. vậy điều xảy ra là giá trị của 30 đi vào đây 30. so what happens is that the value of 30 goes in here 999 01:21:18,780 --> 01:21:26,159 thì 30 sẽ cộng 3 33 và khi đó chúng ta sẽ đi vào logic chính nên 33 cộng 2 sẽ là then 30 will be plus 3 33 and then we'll go into main logic so 33 plus 2 will be 1000 01:21:26,159 --> 01:21:33,060 35 như bạn thấy được in ra ở đây nhé bây giờ các đối số trong Swift cho các hàm có thể 35 as you can see printed out here okay now arguments in Swift for functions can 1001 01:21:33,060 --> 01:21:38,159 cũng có các giá trị mặc định để bạn có thể có ví dụ như một hàm có nội dung Funk also have default values so you can have for instance a function that says Funk 1002 01:21:38,159 --> 01:21:42,360 lấy tên đầy đủ như bạn có thể thấy ở đây được rồi chúng tôi nói tên là tên của gets full name as you can see in here okay we say first name is the name of 1003 01:21:42,360 --> 01:21:46,679 lập luận bên trong và bên ngoài nó có giá trị mặc định là Foo và sau đó the argument internally and externally it has the default value of Foo and then 1004 01:21:46,679 --> 01:21:51,420 chúng ta có thể nói họ là một chuỗi và nó rất tiếc giá trị mặc định của thanh we can say last name is a string and it has the oops the default value of bar 1005 01:21:51,420 --> 01:21:57,840 được rồi và hàm này trả về một chuỗi giống như thế này chúng tôi đặt tên okay and this function returns a string which is like this we put the first name 1006 01:21:57,840 --> 01:22:02,820 ở đây và một khoảng trắng và họ tất cả đúng vậy về cơ bản chúng tôi đang tính toán một in here and a space and last name all right so we're basically calculating a 1007 01:22:02,820 --> 01:22:07,140 tên đầy đủ bằng cú pháp này bây giờ bạn có thể gọi chức năng này bây giờ trong rất nhiều full name using this syntax now you can call this function now in so many 1008 01:22:07,140 --> 01:22:10,860 thực ra bạn có thể gọi theo nhiều cách khác nhau ba cách khác nhau tôi sẽ nói một là different ways actually you can call in three different ways I would say one is 1009 01:22:10,860 --> 01:22:16,159 không có đối số như vậy bởi vì cả hai các đối số có sẵn without arguments so because both the arguments that are available that are 1010 01:22:16,159 --> 01:22:20,340 cần thiết cho chức năng này có mặc định giá trị để bạn không phải vượt qua bất kỳ required for this function have default values so you don't have to pass any 1011 01:22:20,340 --> 01:22:25,020 tranh luận với nó và bạn cũng có thể trộn và match bạn có thể thực sự vượt qua arguments to it and you can also mix and match you can for instance pass actually 1012 01:22:25,020 --> 01:22:28,440 Tôi nghĩ bạn có thể gọi nó trong bốn theo nhiều cách khác nhau, vâng, vì vậy bạn cũng có thể gọi I think you can call it in four different ways yes so you can also call 1013 01:22:28,440 --> 01:22:32,940 nó chỉ có tên nếu bạn muốn nên bạn có thể nói âm trầm bạn có thể nói bạn có thể it only with a first name if you want to so you can say bass you can say you can 1014 01:22:32,940 --> 01:22:37,620 xem bây giờ kết quả sẽ là bazbar nên họ được chọn từ mặc định see now the result will be bazbar so the last name is picked from the default 1015 01:22:37,620 --> 01:22:41,520 giá trị và tên đầu tiên được ghi đè theo giá trị tại địa điểm cuộc gọi value and the first name is overwritten by the value at call site 1016 01:22:41,520 --> 01:22:45,719 và bạn cũng có thể nói lấy tên đầy đủ và sau đó chúng tôi nói chỉ chuyển họ and you can also say get full name and then we say only pass the last name 1017 01:22:45,719 --> 01:22:50,640 giả sử Foo vậy bây giờ giá trị sẽ là Fufu đúng rồi let's say Foo so now the value will be Fufu right 1018 01:22:50,640 --> 01:22:54,960 và sau đó bạn cũng có thể gọi nó bằng cả hai thông số để bạn có thể nói tên và and then you can also call it with both parameters so you can say first name and 1019 01:22:54,960 --> 01:23:01,320 chúng ta nói Babs và họ chúng ta có thể nói những con gà trống như thế này được rồi để bạn có thể thấy we say Babs and last name we can say like this all right so you can see 1020 01:23:01,320 --> 01:23:06,840 bây giờ kết quả sẽ là baz và Cox trong ở đây được rồi nên đây chỉ là một số now the result will be baz and Cox in here all right so these were just some 1021 01:23:06,840 --> 01:23:13,920 ví dụ về cách bạn có thể tạo các hàm trong Swift bây giờ chúng ta sẽ thực sự xem xét nhiều hơn examples of how you can create functions in Swift now we will actually look more 1022 01:23:13,920 --> 01:23:17,640 tại các chức năng về cách tạo thêm chức năng phức tạp có lẽ nhưng đây là at functions on how to create more complex functions perhaps but this is 1023 01:23:17,640 --> 01:23:22,800 giống như cấu trúc cơ bản về cách tạo các hàm trong Swift và có like the basic structure of how to create functions in Swift and there are 1024 01:23:22,800 --> 01:23:26,159 một số chức năng tất nhiên là rất nhiều phức tạp hơn những gì chúng ta có trong some functions of course that are a lot more complicated than what we have in 1025 01:23:26,159 --> 01:23:31,260 ở đây nhưng sự phức tạp thường là bên trong hàm đó, hàm đó here but the complication is usually inside the function itself the function 1026 01:23:31,260 --> 01:23:35,760 ừm tiêu đề hoặc chữ ký hàm là thường là một dạng của những thứ này um header or the function signature is usually one form of these things that 1027 01:23:35,760 --> 01:23:39,659 chúng tôi đã viết ở đây với một số thông số với một số lập luận có lẽ có we've written in here with some param with some arguments that perhaps have 1028 01:23:39,659 --> 01:23:43,500 tên nội bộ hoặc bên ngoài hoặc một số đối số không có tên bên ngoài internal or external names or some arguments that have no external names 1029 01:23:43,500 --> 01:23:48,000 nhưng kết quả có thể loại bỏ tên nội bộ và gần như chỉ thế thôi but internal names discardable result and pretty much pretty much that's it 1030 01:23:48,000 --> 01:23:53,699 thực sự thì bây giờ đó là về các chức năng trong phần tiếp theo của video này really so that's about functions for now in the next section of uh this video 1031 01:23:53,699 --> 01:23:57,659 chúng ta sẽ xem xét việc đóng cửa đó là những loại chức năng đặc biệt nên we're going to have a look at closures which are kind of special functions so 1032 01:23:57,659 --> 01:24:01,739 hẹn gặp bạn ở đó sau khi chúng ta đã hoàn thành nói về chức năng chúng ta hãy tiếp tục see you there now that we've finished talking about functions let's go ahead 1033 01:24:01,739 --> 01:24:05,520 và nói về một loại đặc biệt hàm có các biến cục bộ and talk about a special kind of function which is with local variables 1034 01:24:05,520 --> 01:24:10,679 và nó được gọi là đóng cửa vì vậy trước khi chúng tôi làm hãy cùng tạo ra and it is called closure so before we do that let's create 1035 01:24:10,679 --> 01:24:15,000 sân chơi riêng của nó nên tôi sẽ đi ở đây và nói lệnh n và gõ its own playground so I'm going to go here and say command n and type 1036 01:24:15,000 --> 01:24:20,760 sân chơi ở đây nếu tôi có thể đánh vần nó và trong sân chơi trống tôi sẽ playground in here if I can spell it and in blank playground I'm going to 1037 01:24:20,760 --> 01:24:26,940 tạo các bao đóng ở đây và Đảm bảo lại rằng nó được tạo trong không gian làm việc của bạn và create closures in here and Ensure again that it is created in your workspace and 1038 01:24:26,940 --> 01:24:31,320 không ở trong sân chơi khác Tôi sẽ nhấn nút tạo và not inside another playground I'm going to press the create button and 1039 01:24:31,320 --> 01:24:36,480 hãy nói ở đây rằng import Foundation được rồi bây giờ let's say in here that import Foundation okay now 1040 01:24:36,480 --> 01:24:40,920 đóng cửa có sẵn ở nhiều nơi khác ngôn ngữ lập trình như python closures are available in many other programming languages such as python 1041 01:24:40,920 --> 01:24:46,140 cũng có sẵn trong Phi tiêu chẳng hạn và tôi sẽ nói there are also available available in Dart for instance and in I would say 1042 01:24:46,140 --> 01:24:50,520 rỉ sét và tất nhiên là cả JavaScript và bản đánh máy rust as well and of course JavaScript and typescript 1043 01:24:50,520 --> 01:24:55,860 vì vậy hầu hết các ngôn ngữ lập trình hiện đại có những lần đóng cửa và những lần đóng cửa thực sự là gì so most modern programming languages have closures and what closures really 1044 01:24:55,860 --> 01:25:01,860 có những loại chức năng đặc biệt nào không được tạo thẳng hàng để bạn có thể are there are special types of functions that are created in line so that you can 1045 01:25:01,860 --> 01:25:06,360 thực sự chuyển chúng sang chức năng khác chẳng hạn và họ có thể giữ một actually pass them to another function for instance and they can hold a 1046 01:25:06,360 --> 01:25:09,000 hoạt động để bạn có thể làm đẹp nhiều người nói rằng có chức năng function so you could you could pretty much say that there are function 1047 01:25:09,000 --> 01:25:14,580 kiểu tài liệu tham khảo nhưng không hẳn là vậy, nhưng Tôi nghĩ cách dễ nhất để giải thích references kind of but not really uh but I think the easiest way to explain 1048 01:25:14,580 --> 01:25:19,620 việc đóng cửa là để chứng minh chúng trông như thế nào như cú pháp trông như thế nào closures is to demonstrate how they look like how to how the syntax looks like 1049 01:25:19,620 --> 01:25:25,440 và tôi nghĩ sau đó sẽ có rất nhiều hơn nữa nó sẽ dễ dàng hơn rất nhiều and I think after that it will be a lot more uh it it will be a lot easier to 1050 01:25:25,440 --> 01:25:30,420 hiểu cơ bản họ làm gì hãy tiếp tục và tạo một kết thúc trong understand what basically they do so let's go ahead and create a closure in 1051 01:25:30,420 --> 01:25:34,800 ở đây được cho là thêm hai các số nguyên với nhau và trả về một kết quả here which is supposed to add two integers together and return a result so 1052 01:25:34,800 --> 01:25:39,120 nếu bạn làm điều đó bằng cách sử dụng một hàm bạn có thể sẽ thêm và sau đó bạn if you were to do that using a function you would probably do add and then you 1053 01:25:39,120 --> 01:25:44,280 sẽ nói như bên trái vào của bạn số nguyên bên phải uh và bạn có thể would say like left hand side into your right hand side integer uh and you could 1054 01:25:44,280 --> 01:25:49,080 có lẽ cũng loại bỏ nhãn bên ngoài của những lập luận này để bạn không perhaps also remove the external label of these arguments so that you don't 1055 01:25:49,080 --> 01:25:53,699 thực sự phải viết LHS rhs khi bạn đang gọi chức năng này thì bạn have to actually write LHS rhs when you're calling this function then you 1056 01:25:53,699 --> 01:25:56,580 sẽ nói rằng hàm này trả về một số nguyên thì bạn có thể nói tay trái would say that this function returns an integer then you could say left hand 1057 01:25:56,580 --> 01:25:59,580 cạnh cộng với vế phải là thế chức năng side plus right hand side is that function 1058 01:25:59,580 --> 01:26:05,040 tuy nhiên nếu bạn muốn gán cái này cho một biến ví dụ gọi lúc đó bạn however if you want to assign this to a variable for instance call at then you 1059 01:26:05,040 --> 01:26:10,320 có thể nói hãy thực sự bình luận điều này out thì bạn có thể nói hãy cộng then như could say let's actually comment this out then you could say let's add then as 1060 01:26:10,320 --> 01:26:14,580 bạn sẽ làm với bất kỳ biến nào khác mà bạn như bạn thực sự có thể làm với bất kỳ thứ gì khác you would do with any other variable you as you could do actually with any other 1061 01:26:14,580 --> 01:26:19,320 biến bạn không phải làm điều đó nhưng bạn cần cho Swift biết loại dữ liệu variable you don't have to do that but you need to tell Swift what type of data 1062 01:26:19,320 --> 01:26:24,480 gõ chức năng này được chấp nhận vì vậy bạn có thể nói hãy cộng và sau đó bạn sẽ type this function is accepting so you could say let's add and then you would 1063 01:26:24,480 --> 01:26:29,100 nói cột và thay vì ví dụ nói rằng đây là một số nguyên bằng một say column and instead of for instance saying this is an integer equal to one 1064 01:26:29,100 --> 01:26:33,480 hoặc đây là một chuỗi bằng Foo you có thể nói ở đây rằng đây thực sự là or this is a string equal to Foo you could say in here that this is actually 1065 01:26:33,480 --> 01:26:37,440 một chức năng đúng và sau đó bạn nói được nó chấp nhận a function right and then you say okay it accepts 1066 01:26:37,440 --> 01:26:42,780 một số nguyên và nó thực sự chấp nhận hai số nguyên và nó trả về một số nguyên được an integer and it actually accepts two integers and it returns an integer okay 1067 01:26:42,780 --> 01:26:49,020 vậy đây là bạn đang xác định kiểu dữ liệu của biến này hoặc một sự đóng cửa được rồi và sau đó so this is you defining the data type of this variable or a closure okay and then 1068 01:26:49,020 --> 01:26:53,340 bạn có thể nói nó bằng với so bây giờ bây giờ bạn đã xác định một kiểu dữ liệu you could say it's equal to so now you've defined a data type now you 1069 01:26:53,340 --> 01:26:57,179 thực sự tạo ra chức năng sau đó bên trong việc tạo ra chức năng bạn vừa actually create the function then inside the creation of the function you just 1070 01:26:57,179 --> 01:27:01,260 tạo dấu ngoặc nhọn như bạn sẽ làm bất kỳ chức năng nào khác và ở đây thì bạn create curly brackets as you would do any other function and in here then you 1071 01:27:01,260 --> 01:27:05,040 lấy dữ liệu của bạn, bạn nói phía bên trái là một số nguyên bên phải là một số nguyên get your data you say left hand side is an integer right hand side is an integer 1072 01:27:05,040 --> 01:27:08,580 được rồi và bạn trả về một số nguyên okay and you return an integer 1073 01:27:08,580 --> 01:27:13,139 và sau đó bạn nói như thế này, vậy hãy thực sự phá vỡ điều này mang nó đến and then you say in like this so let's actually break this down bring it to the 1074 01:27:13,139 --> 01:27:17,340 hàng tiếp theo như thế này được rồi vậy đây là nơi bạn đang ở next line like this okay so this is where you're 1075 01:27:17,340 --> 01:27:21,179 xác định kiểu dữ liệu cho ADD và điều này thực sự là nơi bạn đang gán nó cho defining the data type for ADD and this is where you're actually assigning it to 1076 01:27:21,179 --> 01:27:26,159 một chức năng hợp lệ được rồi và hãy thay đổi sân chơi của chúng tôi thành tự động a valid function all right and let's change our playground to automatically 1077 01:27:26,159 --> 01:27:30,179 chạy vào đây và sau đó bạn có thể thấy Swift đang nói với bạn rằng bạn sẽ không quay trở lại run in here and then you can see Swift is telling you that you're not returning 1078 01:27:30,179 --> 01:27:35,100 có gì ở đây nên cứ nói LHS cộng với rhs được rồi và những giá trị này mà chúng tôi anything in here so let's just say LHS plus rhs okay and these values that we 1079 01:27:35,100 --> 01:27:40,380 có ở đây họ chỉ là nội bộ thôi tên đối số nên chúng không thực sự have in here they're just internal uh argument names so they're not actually 1080 01:27:40,380 --> 01:27:45,540 được sử dụng bên ngoài, giờ chúng ta ổn rồi có THÊM bạn có thể thấy nó cho bạn biết rằng being used externally okay now that we have ADD you can see it tells you that 1081 01:27:45,540 --> 01:27:49,860 add thực sự là bất biến mà điểm đến hàm F yêu cầu hai add is actually invariable that points to F function which requires two 1082 01:27:49,860 --> 01:27:55,980 đối số và trả về cũng là một số nguyên vì vậy bạn có thể gọi theo cách bạn muốn arguments and returns also an integer so you could call at just like you would 1083 01:27:55,980 --> 01:28:01,560 gọi hàm thêm vì vậy nếu bạn nói thêm 20 và 30 bạn có thể thấy mình xinh đẹp call the add function so if you say add 20 and 30 you can see that you're pretty 1084 01:28:01,560 --> 01:28:07,199 chỉ cần gọi chức năng đó là bên dưới biến thêm này bạn có thể nói much just calling that function that is beneath this add variable you could say 1085 01:28:07,199 --> 01:28:13,800 được rồi vậy là bạn nhận được kết quả là 30. vậy bây giờ bạn đã biết cách tạo một cái okay so you get the result of 30. so now that you know how to create one 1086 01:28:13,800 --> 01:28:18,600 trong số các lần đóng chức năng này bạn có thể thấy bạn có thể tạo nó theo dòng như thế bạn of these functions closures you can see you can create it in line like that you 1087 01:28:18,600 --> 01:28:24,060 thực sự có thể vượt qua bất kỳ một trong những chức năng như thế này và bạn can actually pass any one of these functions like these and which you 1088 01:28:24,060 --> 01:28:28,560 tạo nội tuyến cho chức năng khác và đó là nơi sức mạnh của sự đóng cửa create inline to another function and that's where the power of closures 1089 01:28:28,560 --> 01:28:33,540 thực sự đến chơi vì vậy hãy tạo một một chức năng khá vô dụng và chúng tôi really come to play so let's create a quite a useless function and that we 1090 01:28:33,540 --> 01:28:37,620 gọi THÊM tùy chỉnh nhưng nó chỉ ở đó nhằm mục đích thể hiện call custom ADD but it's just there for for the purpose of demonstration of 1091 01:28:37,620 --> 01:28:42,239 sự đóng cửa vậy chức năng tùy chỉnh này nó làm gì closures so this custom function what it does it 1092 01:28:42,239 --> 01:28:48,360 phải mất hai biến số nguyên và sau đó nó sử dụng chức năng khác mà bạn cung cấp it takes two integer variables and then it uses another function that you give 1093 01:28:48,360 --> 01:28:53,280 nó để bạn truyền một hàm cho cái này chức năng và chức năng đó được truyền cho it so you pass a function to this function and that function is passed to 1094 01:28:53,280 --> 01:28:58,380 chức năng này sẽ thực hiện hàm cộng và hàm R mà chúng ta sẽ this function will do the actual addition and R function that we will 1095 01:28:58,380 --> 01:29:03,239 tạo bây giờ sẽ chỉ gọi hàm đó được rồi, nó sẽ chỉ chứng minh create now will just call that function all right so it will just demonstrate 1096 01:29:03,239 --> 01:29:06,719 làm thế nào bạn có thể chuyển một chức năng cho người khác chức năng và cách bạn có thể tạo một how you can pass a function to another function and how you can create a 1097 01:29:06,719 --> 01:29:11,820 hoạt động khi đang di chuyển hoặc đang di chuyển hãy tạo hàm THÊM tùy chỉnh này trong function on the go or on the fly so let's create this custom ADD function in 1098 01:29:11,820 --> 01:29:18,540 ở đây chúng ta gọi nó là quảng cáo tùy chỉnh như thế này nhé và quảng cáo tùy chỉnh này phải mất hai ừ hai here we call it custom ad like this okay and this custom ads it takes two uh two 1099 01:29:18,540 --> 01:29:24,239 các giá trị chúng tôi gọi là LHS phía bên trái được rồi và sau đó chúng ta nói câu khác values we call them LHS left hand side all right and then we say rhs another 1100 01:29:24,239 --> 01:29:29,400 số nguyên và là tham số thứ hai, chúng tôi thực sự muốn một chức năng thực hiện integer and as the second parameter we want actually a function that does the 1101 01:29:29,400 --> 01:29:33,960 bổ sung cho chúng tôi nên bản thân quảng cáo tùy chỉnh này nó không thực sự làm việc bổ sung addition for us so this custom ad itself doesn't really do the addition it will 1102 01:29:33,960 --> 01:29:39,179 giao nhiệm vụ bổ sung cho nhiệm vụ đã cho hoạt động giống như bạn định nghĩa delegate the addition task to the given function so just like you would Define 1103 01:29:39,179 --> 01:29:43,500 bất kỳ biến nào khác như ở đây bạn về cơ bản gõ đối số bên ngoài any other variable like here you basically type the external argument 1104 01:29:43,500 --> 01:29:48,060 tên đối số nội bộ tên hoặc chỉ một tên đối số được sử dụng name internal argument name or just one argument name that is used 1105 01:29:48,060 --> 01:29:52,739 bên ngoài và bên trong và sau đó bạn sẽ xác định kiểu dữ liệu của nó, điều này rất externally and internally and then you would Define its data type this is very 1106 01:29:52,739 --> 01:29:56,400 tương tự như bạn thấy việc xác định một kiểu dữ liệu với một cột chúng tôi đã làm điều tương tự trong similar you see defining a data type with a column we did the same thing in 1107 01:29:56,400 --> 01:30:01,500 ở đây vì vậy về cơ bản chúng tôi muốn có một hàm lấy một hoặc hai số nguyên here so we want basically a function that takes an integer or two integers 1108 01:30:01,500 --> 01:30:06,420 và trả về một số nguyên vì vậy hãy tiếp tục và Xác định nó ở đây chúng ta nói bên ngoài and returns an integer so let's go ahead and Define it here we say the external 1109 01:30:06,420 --> 01:30:11,880 nhãn cho đối số này đang được sử dụng nên chúng tôi có thể nói loại quảng cáo tùy chỉnh như thế này label for this argument is using so we can say custom ad kind of like this 1110 01:30:11,880 --> 01:30:18,360 tùy chỉnh lúc 10 20 dùng như thế này nhé vì vậy tên bên ngoài của đối số này là custom at 10 20 using like this okay so the external name of this argument is 1111 01:30:18,360 --> 01:30:23,219 sử dụng và nội bộ được gọi là chức năng được rồi và sau đó chúng ta nói chức năng này using and internally is called function all right and then we say this function 1112 01:30:23,219 --> 01:30:28,620 yêu cầu hai số nguyên và nó trả về một số nguyên được rồi nên nó giống như vậy requires two integers and it returns an integer all right so this is just like 1113 01:30:28,620 --> 01:30:32,940 xác định bất kỳ biến nào khác bên trong hoặc đối số bên trong chữ ký hàm của bạn defining any other variable inside or argument inside your function signature 1114 01:30:32,940 --> 01:30:37,860 bạn chỉ nói xin lỗi dữ liệu bên ngoài tên đối số bên ngoài đối số bên trong you just say external data sorry external argument name internal argument 1115 01:30:37,860 --> 01:30:41,699 đặt tên cho kiểu dữ liệu và kiểu dữ liệu của nó là gần như chỉ là một hàm có hai name it's data type and its data type is pretty much just a function with two 1116 01:30:41,699 --> 01:30:46,800 số nguyên làm đối số và trả về một số nguyên được rồi sau khi làm điều đó chúng ta đóng integers as arguments and returns an integer okay after doing that we close 1117 01:30:46,800 --> 01:30:50,760 danh sách đối số có phần kết thúc dấu ngoặc đơn và bây giờ chúng ta phải xác định the arguments list with the closing parenthesis and now we have to define 1118 01:30:50,760 --> 01:30:55,380 giá trị trả về của hàm R nên điều này chức năng THÊM tùy chỉnh tại thời điểm này bạn the return value of R function so this custom ADD function at the moment you 1119 01:30:55,380 --> 01:30:59,040 có thể thấy nó không trả lại bất cứ thứ gì bởi vì dấu ngoặc đơn kết thúc ở đây nhưng chúng tôi can see it's not returning anything because the parenthesis ends here but we 1120 01:30:59,040 --> 01:31:02,760 không có bất kỳ gợi ý nào ở đây vì vậy hãy nói rằng chức năng của chúng tôi cũng don't have any of these pointers in here so let's say that our function also 1121 01:31:02,760 --> 01:31:08,100 trả về một số nguyên được rồi bên trong tự hoạt động bên trong phép toán tùy chỉnh này returns an integer okay then inside the function itself inside this custom math 1122 01:31:08,100 --> 01:31:12,179 hàm chúng ta cần trả về một số nguyên nhưng chính chức năng này làm được điều đó function we need to return an integer but it is this function that does the 1123 01:31:12,179 --> 01:31:15,719 tính toán vì vậy hãy gọi nó là chỉ giống như bạn sẽ gọi bất kỳ chức năng nào khác calculation so let's just call it just like you would call any other function 1124 01:31:15,719 --> 01:31:21,659 vì vậy chúng ta chỉ nói hàm LHS và rhs và một lần nữa đây chỉ là một nhãn hiệu, nó không so we just say function LHS and rhs and again this is just a label it doesn't 1125 01:31:21,659 --> 01:31:25,380 phải được gọi là chức năng bạn chỉ có thể gọi nó là f nếu bạn muốn hoặc bạn chỉ có thể have to be called function you can just call it f if you want to or you can just 1126 01:31:25,380 --> 01:31:30,540 gọi nó là lh bất cứ điều gì bạn muốn nhưng tôi thực sự thực sự khuyên bạn không nên call it l h whatever you want to but I really really suggest that you don't 1127 01:31:30,540 --> 01:31:34,860 đặt tên cho các biến của bạn bằng f hoặc H hoặc L tốt hơn hết là cứ gọi cho họ name your variables with f or H or L it's just better just to call them 1128 01:31:34,860 --> 01:31:38,699 một cái gì đó và điều đó có nghĩa là một cái gì đó như được rồi và trong trường hợp này tôi hoạt động something and that means something as well okay and in this case function I 1129 01:31:38,699 --> 01:31:44,760 nghĩ là một cái tên khá hay cho nó nhưng bạn có thể không đồng ý think is a quite a good name for it but you might disagree 1130 01:31:44,760 --> 01:31:49,199 vì vậy bây giờ chúng tôi có chức năng và bạn có thể thấy nó đang được gọi bởi các phần bổ trợ tùy chỉnh và so we have function now and you can see it is being called by custom add-ins and 1131 01:31:49,199 --> 01:31:52,980 kết quả này đang được trả về từ Ứng dụng tùy chỉnh và bạn có thể gọi tùy chỉnh this result is being returned from Custom app and you can call the custom 1132 01:31:52,980 --> 01:31:57,000 chức năng quảng cáo như tôi sẽ chỉ cho bạn bây giờ giả sử quảng cáo tùy chỉnh bạn có thể thấy chúng tôi có ad function as I'll show you now so let's say custom ad you can see we have 1133 01:31:57,000 --> 01:32:02,040 ba tham số được rồi tôi sẽ chia nhỏ chúng ở dưới đây bây giờ phía bên trái bạn có thể three parameters okay I'll break them down here now the left hand side you can 1134 01:32:02,040 --> 01:32:06,719 xem nó không có nhãn bên ngoài nào vậy hãy cứ nói là 20. và sau đó chúng ta nói see it doesn't have any external labels so let's just say 20. and then we say 1135 01:32:06,719 --> 01:32:10,739 30. bây giờ việc sử dụng này sẽ rất thú vị bởi vì thông thường khi bạn 30. now this using is going to be very interesting because usually when you 1136 01:32:10,739 --> 01:32:15,480 đến đây Swift sẽ có thể thay thế cái này cho bạn bằng cách sử dụng a come here Swift is going to be able to substitute this for you using an a 1137 01:32:15,480 --> 01:32:21,480 cú pháp đóng dấu được rồi nên nếu tôi đi ở đây và nhấn enter bạn có thể thấy tất cả trailing closure syntax okay so if I go here and press enter you can see all of 1138 01:32:21,480 --> 01:32:26,699 đột nhiên nhãn sử dụng chỉ là hoàn toàn bị loại bỏ ngay bây giờ nếu bạn đi a sudden the using label was just completely removed now if if you go 1139 01:32:26,699 --> 01:32:31,260 phía trước ở đây và bạn chỉ muốn xem được rồi nhưng chuyện gì đang xảy ra ở đây vậy ahead in here and you just want to see okay but what is happening in here what 1140 01:32:31,260 --> 01:32:34,560 thay vào đó bạn có thể làm là tiếp tục và tạo một chức năng ở đây bởi vì điều này you could do is instead go ahead and create a function in here because this 1141 01:32:34,560 --> 01:32:36,960 bạn có thể thấy nó là một chức năng nói với bạn rằng nó cần phải có hai should be a function you see it's telling you it needs to have two 1142 01:32:36,960 --> 01:32:41,699 đối số và giá trị trả về của số nguyên bạn có thể tự tạo một hàm và arguments and a return value of integer you could create a function yourself and 1143 01:32:41,699 --> 01:32:47,040 sau đó nói bên tay trái và tay phải kết thúc bên và nó sẽ trả về INT then say left hand side and right hand side ends and it should return an INT 1144 01:32:47,040 --> 01:32:51,719 và sau đó bạn vào đây và cũng xin vui lòng đừng quên cú pháp vì nó and then in here you and also please don't forget the in syntax because it 1145 01:32:51,719 --> 01:32:56,460 cần biết Swift cần biết ở đâu chức năng này thực sự bắt đầu phần thân của nó needs to know Swift needs to know where this function actually starts its body 1146 01:32:56,460 --> 01:33:01,620 được rồi ở đây bạn nói phía bên trái cộng với phía bên phải nên sau khi làm điều này okay then in here you say left hand side plus right hand side so after doing this 1147 01:33:01,620 --> 01:33:06,540 bây giờ bạn có thể thấy giá trị của 50 là được in ra bảng điều khiển sân chơi tất cả you can see now the value of 50 being printed to the playground console all 1148 01:33:06,540 --> 01:33:12,480 đúng vậy đó là những gì bạn có thể làm tuy nhiên cú pháp thủ công Swift là gì right so that's what you could do manually however what syntax what Swift 1149 01:33:12,480 --> 01:33:18,600 đó là nếu nó nhìn thấy một đối số tại sự kết thúc của một chức năng bạn có thể thấy xin lỗi does is that if it sees an argument at the end of a function you can see sorry 1150 01:33:18,600 --> 01:33:22,500 một đối số ở cuối danh sách đối số của một hàm nên ở đây chúng ta có an argument at the end of the list of arguments of a function so here we have 1151 01:33:22,500 --> 01:33:26,159 một bên tay trái và một bên tay phải và sau đó chúng ta có một kết thúc a left hand side and right hand side and then we have a closure 1152 01:33:26,159 --> 01:33:31,139 cái đó phải được chuyển tới hàm này nhưng tiết lộ không giống như lần đầu that has to be passed to this function but disclosure is not like the first 1153 01:33:31,139 --> 01:33:36,960 đối số đó là đối số cuối cùng và Swift thực hiện một thứ gọi là dấu vết argument it is the last argument and Swift does something called a trailing 1154 01:33:36,960 --> 01:33:42,120 cú pháp đóng cửa nó làm gì và chúng ta thực sự có thể làm điều đó bằng tay, chúng ta có thể đi closure syntax what it does is that and we can actually do it by hand we can go 1155 01:33:42,120 --> 01:33:46,620 ở đây bạn có thể thấy nó loại bỏ cái này tên đối số trước hết in here you can see it removes this argument name first of all 1156 01:33:46,620 --> 01:33:52,860 sau đó nó đặt dấu ngoặc đơn kết thúc ở đây và sau đó loại bỏ cột này then it puts an ending parenthesis here and then removes this column 1157 01:33:52,860 --> 01:33:57,420 thì bạn có thể thấy điều này khá nhiều làm điều tương tự ở đây và sau đó nó then you can see this should pretty much do the same thing in here so and then it 1158 01:33:57,420 --> 01:34:01,080 tất nhiên loại bỏ dấu ngoặc đơn này trong ở đây là tốt of course removes this parenthesis in here as well 1159 01:34:01,080 --> 01:34:06,000 vậy bây giờ bạn có thể thấy dấu ngoặc đơn kết thúc ở đây và sau đó không còn sử dụng nữa vì so now you can see the parenthesis ends here and then there's no using since 1160 01:34:06,000 --> 01:34:10,260 sử dụng tên đối số và sau đó có một đóng cửa ngay sau using argument name and then there is a trailing closure right after the 1161 01:34:10,260 --> 01:34:14,820 chức năng đã kết thúc nên chúng ta thực sự có thể đặt cái này có lẽ ở đây thực ra nó tốt function is finished so we can actually put this maybe here actually it's good 1162 01:34:14,820 --> 01:34:20,219 vâng và chúng ta cũng có thể dọn dẹp cái này một chút như thế này nên đây là yeah and we can clean this up as well a little bit like this so this is the 1163 01:34:20,219 --> 01:34:24,420 cú pháp đóng theo dõi theo nghĩa Swift rằng nếu có sự đóng cửa ở cuối trailing closure syntax in Swift meaning that if there is a closure at the end of 1164 01:34:24,420 --> 01:34:29,880 một chức năng và sau đó nó không nên không nhất thiết phải có tất cả a function and then it shouldn't it doesn't necessarily have to have all the 1165 01:34:29,880 --> 01:34:35,820 chuông và còi xung quanh cuộc tranh luận tên và v.v. được thôi, nó chỉ có thể phát ra bells and whistles around uh argument names and Etc okay it can just emit 1166 01:34:35,820 --> 01:34:40,920 viết tên đối số đóng dấu ngoặc đơn ngay sau đối số writing the argument name close the parenthesis right after the argument 1167 01:34:40,920 --> 01:34:45,360 trước nó và sau đó tạo bao đóng ngay sau lệnh gọi hàm này và nó before it and then creates the closure right after this function call and it 1168 01:34:45,360 --> 01:34:51,360 sẽ được chuyển vào cuộc tranh luận này nhé vậy bây giờ bạn thấy rằng chúng ta đã tạo một kết thúc will be passed into this argument okay so now you saw that we created a closure 1169 01:34:51,360 --> 01:34:55,320 cái này là cái nào và chúng tôi đã chuyển nó cho một chức năng khác đang được thực hiện which is this one and we passed it to another function which is then being 1170 01:34:55,320 --> 01:35:01,159 dùng để tính giá trị của 20 cộng 30 được rồi used to calculate the value of 20 plus 30 okay 1171 01:35:01,159 --> 01:35:09,179 bây giờ Swift cũng có một tính năng rất tiện dụng chức năng nơi nó có thể suy ra dữ liệu now Swift also has a very handy functionality where it can infer data 1172 01:35:09,179 --> 01:35:13,860 các loại dựa trên chữ ký hàm bây giờ tôi sẽ giải thích điều này một chút types based on the function signature now I'll explain this a little bit now 1173 01:35:13,860 --> 01:35:18,960 và bạn có thể thấy ở đây chức năng này quảng cáo tùy chỉnh đã xác định rằng and you can see in here this function custom ad already has defined that the 1174 01:35:18,960 --> 01:35:23,940 việc đóng cửa được truyền cho hàm đối số phải có kiểu dữ liệu là closure being passed to the function argument has to have the data type of 1175 01:35:23,940 --> 01:35:28,860 số nguyên và nó xin lỗi nó phải có kiểu dữ liệu số nguyên cho cả hai integer integer and it sorry it has to have the data type of integer for both 1176 01:35:28,860 --> 01:35:32,699 các đối số của nó và cả số nguyên đầu tiên giá trị trả về of its arguments and also integer first return value 1177 01:35:32,699 --> 01:35:37,320 bây giờ ở đây bạn có thể nói được nhưng nếu chức năng này đã biết rằng nó now in here then you could say okay but if this function already knows that it 1178 01:35:37,320 --> 01:35:41,159 có lẽ là số nguyên và số nguyên có lẽ tôi chỉ có thể loại bỏ những cái này tốt thôi should be integer and integer maybe I could just remove these well it kind of 1179 01:35:41,159 --> 01:35:44,820 đúng rồi bạn có thể vào đây và nói bên tay trái bên tay phải would be right you can just go in here and say left hand side right hand side 1180 01:35:44,820 --> 01:35:49,260 và sau đó vào và nếu nó chạy lại mã của bạn, bạn and then in and if it runs your code again you 1181 01:35:49,260 --> 01:35:52,980 về cơ bản sẽ gặp lại 50, bạn có thể nhìn vào đây để chúng ta có thể thay đổi should basically see 50 again you can see in here so we could maybe change 1182 01:35:52,980 --> 01:35:58,199 đến 30 chỉ để thấy rằng mọi thứ đều ổn làm việc như mong đợi this to 30 just to see that everything's working as expected 1183 01:35:58,199 --> 01:36:03,480 ừ, chúng ta bắt đầu nhé, chúng ta có giá trị là 60. để bạn có thể loại bỏ những kiểu dữ liệu này uh there we go we got the value of 60. so you can remove these data types 1184 01:36:03,480 --> 01:36:08,420 đúng vậy nếu chúng ta thực sự sao chép cái này mã và mang nó một chút xuống đây right so if let's actually copy this code and bring it a little bit down here 1185 01:36:08,420 --> 01:36:14,040 và xóa các kiểu dữ liệu như thế này và chúng ta cũng có thể loại bỏ giá trị trả về and remove the data types like this and we can remove the return value as well 1186 01:36:14,040 --> 01:36:18,960 vậy đó là bước đầu tiên của việc dọn dẹp mã mà bạn có thể làm ngay bây giờ so that's the first step of cleaning up the code that you can do all right now a 1187 01:36:18,960 --> 01:36:22,620 rất nhiều nhà phát triển sẽ gọi đây là thực ra là dọn dẹp họ sẽ nói ồ vâng lot of developers would call this actually clean up they would say oh yeah 1188 01:36:22,620 --> 01:36:26,699 bạn nên loại bỏ những kiểu dữ liệu này chúng không tốt lắm, v.v. tuy nhiên tôi đã you should remove these data types they're not so good Etc however I've 1189 01:36:26,699 --> 01:36:32,219 đã thực hiện rất nhiều dự án lớn đã được viết hoàn toàn bằng Swift worked on a lot of big projects that have been written in purely in Swift 1190 01:36:32,219 --> 01:36:39,300 và một khi cơ sở mã của bạn trở nên rất rất lớn đến nỗi bạn có thể có hàng ngàn and once your code base gets very very large that you have maybe thousands of 1191 01:36:39,300 --> 01:36:43,440 các tập tin nguồn và sau đó mỗi tập tin đó tập tin nguồn có hàng trăm dòng source files and then every of those source files has hundreds of lines of 1192 01:36:43,440 --> 01:36:47,820 mã số trung bình có lẽ được viết trong đó tôi code on average perhaps written in them I've 1193 01:36:47,820 --> 01:36:50,960 nhận thấy rằng ý tôi là sau khi làm rất nhiều ừ noticed that I mean after doing a lot of uh 1194 01:36:50,960 --> 01:36:57,179 điểm chuẩn trong việc biên soạn và yêu cầu xcode cho tôi biết chính xác ở đâu benchmarking on the compilation and asking xcode to tell me exactly where 1195 01:36:57,179 --> 01:37:02,639 mọi thứ đang mất nhiều thời gian hoặc nhiều nhất thời gian trong quá trình biên soạn nó đã được things are taking a time or the most time during the compilation it's been 1196 01:37:02,639 --> 01:37:07,500 trình biên dịch đã ở đâu cố gắng tìm ra các kiểu dữ liệu where it has where the compiler has been trying to figure out data types so 1197 01:37:07,500 --> 01:37:12,000 có ít thông tin hơn đấy bạn cung cấp cho trình biên dịch nhiều thời gian hơn there's a little less information you give to the compiler the more time it 1198 01:37:12,000 --> 01:37:16,620 cần trình biên dịch để biên dịch mã nên ở đây bạn có thể thấy chúng tôi có rất nhiều takes for the compiler to compile your code so here you can see we have a lot 1199 01:37:16,620 --> 01:37:19,980 thông tin cho trình biên dịch, chúng tôi nói với nó rằng việc đóng cửa này có hai of information for the compiler we're telling it that this closure has two 1200 01:37:19,980 --> 01:37:24,420 đối số là số nguyên và nó trả về một số nguyên nên trình biên dịch không cần phải arguments integers and it's returning an integer so the compiler doesn't have to 1201 01:37:24,420 --> 01:37:29,280 tự mình tìm hiểu nên nó nói ổn sau đó tôi chỉ cần tính toán và trả lại figure it out on its own so it says okay then I just calculate this and return 1202 01:37:29,280 --> 01:37:36,000 tuy nhiên dữ liệu ở đây trình biên dịch có để đảm bảo rằng ừ được rồi nên chức năng the data however here the compiler has to ensure that yeah okay so the function 1203 01:37:36,000 --> 01:37:38,940 nó phải quay lại quảng cáo tùy chỉnh hoạt động và nói ổn, điều này không nên it has to go back to the custom ad function and say okay this shouldn't 1204 01:37:38,940 --> 01:37:42,600 có hai đối số nguyên và nó phải trả lại một ins sau đó nó đến đây và have two integer arguments and it should return an ins then it comes here and 1205 01:37:42,600 --> 01:37:47,400 kiểm tra điều đó bởi vì chúng tôi thậm chí còn chưa nói đó là giá trị trả về mà chúng ta có thì nó checks that because we haven't even told it what return value we have then it 1206 01:37:47,400 --> 01:37:51,179 nói được rồi, có một số dữ liệu ở đây dữ liệu ở đây và chúng phải cộng says okay there's some data here some data in here and they have to be plus 1207 01:37:51,179 --> 01:37:56,219 hai số nguyên có thể cộng được không cùng nhau được rồi nên nó phải tìm ra together can two integers be plus together okay so it's it has to figure 1208 01:37:56,219 --> 01:38:00,420 tự mình tìm ra tất cả những điều này để nó về cơ bản phải tìm kiếm điểm cộng figure out all of this on its own so it has to basically look up the plus 1209 01:38:00,420 --> 01:38:06,719 hàm hoặc trong toán tử nhị phân cố định để đảm bảo rằng điều đó thực sự tồn tại giữa function or in fixed binary operator to ensure that that actually exists between 1210 01:38:06,719 --> 01:38:11,340 hai số nguyên để bạn có thể tưởng tượng tất cả điều này về cơ bản gây căng thẳng cho two integers so you can imagine all of this basically puts strain on the 1211 01:38:11,340 --> 01:38:14,760 trình biên dịch và tất nhiên nếu bạn có hàng ngàn và hàng ngàn trong số này compiler and of course if you have thousands and thousands of these 1212 01:38:14,760 --> 01:38:18,420 các chức năng mà trình biên dịch phải làm tự mình tìm ra mọi thứ sau đó functions that where the compiler has to figure out things on its own then of 1213 01:38:18,420 --> 01:38:21,719 tất nhiên phần tổng hợp của bạn sẽ như vậy chậm hơn đáng kể course your compilation is going to be drastically slower 1214 01:38:21,719 --> 01:38:25,560 bây giờ chúng ta đang nói về loại bỏ thông tin từ trình biên dịch now now that we're talking about stripping information from the compiler 1215 01:38:25,560 --> 01:38:28,980 còn có một bước nữa mà bạn có thể thực hiện để làm cho mã của bạn tốt hơn there's also one more step that you can take in order to make your code more 1216 01:38:28,980 --> 01:38:33,480 Nhỏ gọn và khó khăn hơn cho trình biên dịch để đoán nhưng nhỏ hơn Compact and more difficult for the compiler to guess but on small smaller 1217 01:38:33,480 --> 01:38:37,260 cơ sở mã này là cái này không thực sự thành thật mà nói thì tạo nên sự khác biệt code basis this is this doesn't really make any difference to be honest so 1218 01:38:37,260 --> 01:38:40,920 hãy thực sự sao chép và dán mã này ngay đây bạn có thể làm gì trong trường hợp này let's actually copy and paste this code right here what you can do in this case 1219 01:38:40,920 --> 01:38:46,800 là bạn có thể loại bỏ hoàn toàn những thứ này thông tin này từ đây và trong Swift is that you can completely remove these this information from here and in Swift 1220 01:38:46,800 --> 01:38:51,480 bạn có thể nói với nó rằng bạn có hai đối số ở đây bằng cách chỉ định bởi you can tell it that you have two arguments in here by specifying by 1221 01:38:51,480 --> 01:38:56,280 thêm tiền tố vào mỗi đối số bằng chỉ mục của nó và đô la nên bạn có thể nói đô la bằng không prefixing every argument with its index and dollar so you can say dollar zero 1222 01:38:56,280 --> 01:39:02,100 cộng thêm một đô la nên Dollar ở đây sẽ về cơ bản có nghĩa là một đối số tại một chỉ mục plus dollar one so Dollar in here will mean basically an argument at an index 1223 01:39:02,100 --> 01:39:06,600 bằng 0, đó là anh chàng này và một đối số ở chỉ mục của một trong đó là of zero which is this guy and an argument at the index of one which is 1224 01:39:06,600 --> 01:39:10,440 anh chàng này và sau đó bạn chỉ là cộng thêm chúng lại với nhau và trả về giá trị this guy and then you're just plusing them together and returning the value so 1225 01:39:10,440 --> 01:39:17,699 một số nhà phát triển sau đó sẽ giống như tùy chỉnh vào lúc 20h30 và sau đó chúng ta sẽ làm như thế này some developers will then be like custom at 20 30 and then we'll do like this 1226 01:39:17,699 --> 01:39:22,739 vì vậy điều đó hoàn toàn phụ thuộc vào bạn và bạn đồng đội bạn muốn định dạng như thế nào so it is completely up to you and your teammates how you like to format your 1227 01:39:22,739 --> 01:39:29,460 Swift Code vì không may là có không có kẻ nói dối chính thức thực sự và chính thức Swift Code because unfortunately there's no real official linter and official 1228 01:39:29,460 --> 01:39:35,040 trình định dạng mã cho Swift như tôi đã đề cập trước đây có một số Cộng đồng code formatter for Swift as I mentioned before so there are some Community 1229 01:39:35,040 --> 01:39:39,300 hướng dẫn cách định dạng mã nhưng bạn thực sự không thể thấy mã được viết như thế nào guidelines how to format code but you can't actually see code written like 1230 01:39:39,300 --> 01:39:42,960 điều này đôi khi và thành thật mà nói với bạn đối với tôi ít nhất cái này có thể đọc được, tôi có this sometimes and to be honest with you for me at least this is readable I have 1231 01:39:42,960 --> 01:39:47,219 không có gì chống lại nó nhưng nếu đó là tôi viết mã này có lẽ tôi sẽ viết nothing against it but if it was me writing this code I would probably write 1232 01:39:47,219 --> 01:39:53,639 nó giống như thế này nhiều hơn chỉ vì kinh nghiệm tôi đã có it a lot more like this just because of the experience I've had 1233 01:39:53,639 --> 01:39:58,679 với việc đảm bảo rằng trình biên dịch có thể biên dịch mã của tôi nhanh hơn trên mã lớn hơn with ensuring that the compiler can compile my code faster on larger code 1234 01:39:58,679 --> 01:40:05,100 cơ bản nhưng viết mã như thế này cũng được hoàn toàn ổn tùy thuộc vào ngữ cảnh basis but writing code like this is also completely fine dependent on the context 1235 01:40:05,100 --> 01:40:09,360 được rồi tốt bây giờ chúng ta đã làm xong việc đó hãy all right good now now that we've done that let's 1236 01:40:09,360 --> 01:40:14,340 hãy nhìn vào việc vượt qua ừm một số kiểu đóng cửa đặc biệt để have a look at passing um some sort of special closures to 1237 01:40:14,340 --> 01:40:20,460 chức năng và trước tôi trước khi chúng ta làm điều đó hãy để tôi viết một số mã ở đây vì uh functions and before I before we do that let me just write some coding here as uh 1238 01:40:20,460 --> 01:40:26,280 giống như một sự chuẩn bị, hãy xác định một mảng ở đây và nói và tôi cũng biết like a preparations let's just Define an array in here and say and I'm also aware 1239 01:40:26,280 --> 01:40:30,000 mà chúng ta chưa làm việc với mảng nhưng nếu bạn đã làm việc với người khác that we haven't worked with arrays yet but if you've worked with another 1240 01:40:30,000 --> 01:40:33,719 ngôn ngữ lập trình bạn rồi có lẽ biết mảng là gì nên nó programming language you already probably know what arrays are so it's 1241 01:40:33,719 --> 01:40:39,120 giống như một sự đồng nhất, thực ra họ cũng có thể không đồng nhất nhưng nó just like a homogeneous uh actually they can be heterogeneous as well but it's 1242 01:40:39,120 --> 01:40:42,840 giống như một chuỗi dữ liệu được rồi, hãy cứ để nó ở đó hãy nói just like a series of data okay let's just leave it at that let's just say 1243 01:40:42,840 --> 01:40:49,080 tuổi là 30 20 19 và 40. vậy bây giờ chúng ta có bốn số nguyên được đặt bên trong mảng này ages are 30 20 19 and 40. so now we have four integers placed inside this array 1244 01:40:49,080 --> 01:40:55,020 được rồi bây giờ bạn có thể thấy ở đây chúng ta có thể bắt đầu sắp xếp mảng này hãy nói rằng okay now you can see in here we can start sorting this array let's say that 1245 01:40:55,020 --> 01:40:59,760 chúng tôi muốn sắp xếp mọi thứ tăng dần và giảm dần nên chúng tôi nói đã sắp xếp được rồi còn bạn we want to sort things ascending and descending so we say sorted okay and you 1246 01:40:59,760 --> 01:41:04,500 có thể thấy nó có một đối số ở đây và có một chức năng gọi là sắp xếp bằng cách sử dụng can see it has an argument in here and there's a function called sorted using 1247 01:41:04,500 --> 01:41:08,580 thực ra hãy nói sắp xếp theo hãy nói sắp xếp theo cái này tốt hơn một chút actually let's just say sorted by let's say sorted by this a little bit better 1248 01:41:08,580 --> 01:41:13,739 và bạn có thể thấy nó mong đợi một chức năng nó nói hãy cho tôi một chức năng để thực hiện and you can see it expects a function so it says give me a function that takes 1249 01:41:13,739 --> 01:41:18,300 hai số nguyên và sau đó nó có thể ném và chúng ta chưa nói về việc ném nó và nó two integers and then it can throw and we haven't talked about throws it and it 1250 01:41:18,300 --> 01:41:23,159 nên trả lại một Boolean được rồi, đi thôi phía trước và xem chúng ta có thể triển khai điều này như thế nào should return a Boolean okay so let's go ahead and see how we can implement this 1251 01:41:23,159 --> 01:41:29,100 hàm nên chúng ta nói số nguyên LHS rhs số nguyên và nó sẽ trả về một giá trị Boolean function so we say LHS integer rhs integer and it should return a Boolean 1252 01:41:29,100 --> 01:41:34,500 được rồi và thực ra nó cũng ném nhưng chúng ta không cần phải viết điều đó và sau đó okay and then actually it throws as well but we don't have to write that and then 1253 01:41:34,500 --> 01:41:40,080 chúng ta nói đồng ý vậy nên hãy vào đây bây giờ hãy trả về true và hãy xem we say in all right so in here let's just return true for now and let's see 1254 01:41:40,080 --> 01:41:45,719 chuyện gì xảy ra thì được, vậy nên nếu bạn trả về đúng ở đây hãy xem dữ liệu đang được what happens okay so if you return true in here let's see the data that is being 1255 01:41:45,719 --> 01:41:51,119 trở lại đây uh ss14 19 20 30. vậy thực sự là không ổn rồi returning here uh ss14 19 20 30. so it really didn't do 1256 01:41:51,119 --> 01:41:59,100 bất cứ điều gì nhưng nếu chúng ta nói ở đây uh LHS nên nhiều hơn rhs được rồi và đây là anything so but if we say in here uh LHS should be more than rhs okay and this is 1257 01:41:59,100 --> 01:42:03,600 tất nhiên nó sẽ trả về một giá trị Boolean giá trị ngay bây giờ bạn có thể thấy những gì of course it's going to return a Boolean value all right now you can see what 1258 01:42:03,600 --> 01:42:09,000 đã xảy ra là kết quả là trở về từ tuổi là được sắp xếp là một happened is that the result is that the return from age is that sorted is an 1259 01:42:09,000 --> 01:42:14,520 mảng được sắp xếp giảm dần như miễn là bên trái nhiều hơn bên phải array that is sorted descending so as long as left hand side is more on right 1260 01:42:14,520 --> 01:42:19,199 về mặt cơ bản nếu bạn đang làm điều này so sánh với lớn hơn thì bạn hand side if you're basically doing this comparison with greater than then you're 1261 01:42:19,199 --> 01:42:22,800 sắp xếp mảng giảm dần và bạn có thể đọc tài liệu nếu chúng tôi sắp xếp sorting the array descending and you can read the documentation if we're sorted 1262 01:42:22,800 --> 01:42:27,300 cũng để hiểu nó thực sự như thế nào hoạt động ổn nên đây là lúc bạn muốn sắp xếp by as well to understand how it actually works okay so it's when you want to sort 1263 01:42:27,300 --> 01:42:31,080 một chuỗi các phần tử không tuân theo blah blah hãy xem và a sequence of elements that don't conform to the blah blah let's see and 1264 01:42:31,080 --> 01:42:34,860 trả về true khi phần tử đầu tiên nên được đặt hàng trước thứ hai vì vậy that returns true when the first element should be ordered before the second so 1265 01:42:34,860 --> 01:42:38,520 nó báo trả về true khi lần đầu tiên phần tử phải được sắp xếp trước it says return true when the first element should be ordered before the 1266 01:42:38,520 --> 01:42:42,719 thứ hai và điều chúng tôi đang nói là nếu bên trái nhiều hơn bên phải second and and what we're saying is that if left hand side is more than the right 1267 01:42:42,719 --> 01:42:46,440 bên tay thì nên sắp xếp trước đây và đó là lý do tại sao chúng tôi nhận được hand side then it should be sorted before and that's why we're getting 1268 01:42:46,440 --> 01:42:49,920 giảm dần và nếu bạn thay đổi điều này thành ít hơn descending and if you change this to less than 1269 01:42:49,920 --> 01:42:55,139 bạn nên mong đợi tỷ lệ của mình được sắp xếp tăng dần được rồi you should expect your rate to be sorted ascending okay 1270 01:42:55,139 --> 01:43:00,119 vậy điều tôi đang cố gắng làm ở đây là rằng chúng tôi có rất nhiều mã ở đây so what what I'm trying to doing here is that we have a lot of code in here you 1271 01:43:00,119 --> 01:43:03,900 có thể thấy điều đó nằm ở phía bên trái và phía bên phải trả về một Boolean can see that takes left hand side and right hand side returns a Boolean 1272 01:43:03,900 --> 01:43:09,179 tuy nhiên như bạn có thể đoán được điều này cụ thể however there as you may guess this particular 1273 01:43:09,179 --> 01:43:12,119 ừm toán tử là một trung tố nhị phân um operator which is a binary infix 1274 01:43:12,119 --> 01:43:16,320 toán tử đã chiếm phía bên trái và phía bên phải và trả về một operator already takes a left hand side and a right hand side and returns a 1275 01:43:16,320 --> 01:43:22,679 Boolean vì vậy nếu chúng ta Def to chúng tôi tự mình thực hiện toán tử uh này Boolean so if we were to Def to implement this uh operator ourselves we 1276 01:43:22,679 --> 01:43:27,360 có lẽ sẽ viết nó như thế này đúng không hoạt động ít hơn và chúng tôi nói tay trái would probably write it like this right function less than and we say left hand 1277 01:43:27,360 --> 01:43:33,060 số nguyên bên phải số nguyên bên phải và nó trả về một Boolean và chúng ta nói left side integer right hand side integer and it returns a Boolean and we say left 1278 01:43:33,060 --> 01:43:36,659 bên tay nhỏ hơn bên phải tuy nhiên xin đừng làm điều này bởi vì hand side less than right hand side however please don't do this because 1279 01:43:36,659 --> 01:43:41,280 điều này thực sự đi vào một cái gì đó được gọi là Vòng lặp vô hạn this actually goes into a something called an infinite Loop 1280 01:43:41,280 --> 01:43:45,600 nó sẽ đi vào một đệ quy vô hạn của chính nó bởi vì chức năng này sẽ chỉ it will go into an infinite recursion of itself because this function will just 1281 01:43:45,600 --> 01:43:51,119 tự gọi nó là được rồi nên điều tôi đang cố gắng để nói ở đây là nếu bạn nhìn vào call itself all right so what I'm trying to say in here is that if you look at 1282 01:43:51,119 --> 01:43:55,380 chữ ký hàm này bạn có thể thấy nó hoàn toàn giống với chức năng này this function signature you can see it is exactly the same as this function 1283 01:43:55,380 --> 01:44:01,560 chữ ký như vậy và vì đây là một chính tên hàm tại sao chúng ta không signature so and since this is a function name in itself why don't we 1284 01:44:01,560 --> 01:44:06,719 chỉ cần chuyển nó sang cái này thay vì viết tất cả những điều này tại sao chúng ta không làm just pass it to this so instead of writing all of this why don't we just do 1285 01:44:06,719 --> 01:44:10,440 cái này đúng bởi vì nó giống nhau this right because it is the same thing it is 1286 01:44:10,440 --> 01:44:13,800 sự thay thế chính xác của cái này vì vậy hãy loại bỏ cái đó the exact substitute of this so let's remove that 1287 01:44:13,800 --> 01:44:18,780 và xóa mã này và bạn có thể thấy thực sự bạn có thể làm điều đó bằng cách and remove this code as well and you can see actually you can do that so by 1288 01:44:18,780 --> 01:44:24,840 truyền một hàm hoặc một toán tử nhị phân trong toán tử sửa cái này sang cái này passing a function or an operator a binary in fix operator to this to this 1289 01:44:24,840 --> 01:44:30,480 lập luận bạn đang thay thế khá nhiều tất cả mã mà chúng tôi đã viết ở đây vì vậy argument you're substituting pretty much all this code that we wrote in here so a 1290 01:44:30,480 --> 01:44:33,900 rất nhiều người mới sử dụng Swift sẽ viết mã như thế này nhưng rất dày dạn lot of newcomers to Swift will write code like this but a lot of seasoned 1291 01:44:33,900 --> 01:44:38,400 các nhà phát triển biết điều đó và điều này toán tử nhị phân và sửa lỗi đã là một developers know that that and this binary and fix operator already is a 1292 01:44:38,400 --> 01:44:43,739 thay thế cho việc đóng cửa đó để bạn có thể làm điều tương tự cho nhiều hơn thế này substitute for that closure so you can do the same thing for more than so this 1293 01:44:43,739 --> 01:44:47,699 sẽ sắp xếp giảm dần và đây là sẽ sắp xếp tăng dần để bạn có thể thấy is going to sort descending and this is going to sort ascending so you can see 1294 01:44:47,699 --> 01:44:52,139 ở đây sắp xếp giảm dần và thanh kiếm tăng dần được rồi here descending sort and ascending sword okay 1295 01:44:52,139 --> 01:44:58,199 Vì thế đó là một ví dụ hay đúng hơn là so that was uh one one example or rather 1296 01:44:58,199 --> 01:45:04,139 hai ví dụ về việc chuyển các toán tử tới đóng cửa được rồi two examples of passing operators to closures okay 1297 01:45:04,139 --> 01:45:08,580 bây giờ hãy chuyển sang ví dụ tiếp theo và vì điều đó tôi sẽ đến đây để now let's move on to the next example and for that I'm gonna go here to our 1298 01:45:08,580 --> 01:45:14,040 chức năng quảng cáo tùy chỉnh và tôi sẽ sao chép nó ngay tại đây và dán nó xuống custom ad function and I'm gonna copy it right right here and let's paste it down 1299 01:45:14,040 --> 01:45:18,780 ở đây và hãy gọi nó là ad2 tùy chỉnh và nếu bạn nhớ tôi đã đề cập rằng chúng ta có here and let's call it custom ad2 and if you remember I mentioned that we have 1300 01:45:18,780 --> 01:45:24,420 cú pháp này về cơ bản được gọi là dấu vết đóng cửa trong Swift có nghĩa là nếu có this syntax called basically trailing closures in Swift meaning that if there 1301 01:45:24,420 --> 01:45:29,159 là một bao đóng ở cuối hàm chữ ký làm danh sách các đối số của nó is a closure at the end of the function signature as its list of arguments then 1302 01:45:29,159 --> 01:45:35,340 Swift giúp bạn bằng cách loại bỏ bởi cho phép bạn loại bỏ và Swift helps you out by removing by allowing you to remove the and the 1303 01:45:35,340 --> 01:45:40,679 nhãn đối số và cho phép nó theo dõi về cơ bản là việc đóng cửa ở cuối argument label and allowing it to Trail basically the closure at the end of the 1304 01:45:40,679 --> 01:45:46,080 gọi hàm như chúng ta đã thấy ở đây vì vậy bạn không cần phải gõ và sử dụng ở đây function call as we saw in here so you don't have to type and using in here 1305 01:45:46,080 --> 01:45:50,460 được rồi đó là điều mà chúng tôi nếu không thì sẽ phải làm tốt thôi okay which is something that we otherwise would have to do all right 1306 01:45:50,460 --> 01:45:56,580 như thế này bằng cách sử dụng cái này và sau đó dấu ngoặc đơn vì vậy chức năng đó như like this using this and then parenthesis so since that function as 1307 01:45:56,580 --> 01:45:59,760 vì cuộc tranh luận này ở cuối nên chúng ta không phải làm tất cả công việc đó since this argument is at the end then we don't have to do all of that work 1308 01:45:59,760 --> 01:46:03,780 tuy nhiên nếu bạn mắc sai lầm khi đặt lập luận này chẳng hạn lúc đầu however if you make a mistake of putting this argument for instance at the first 1309 01:46:03,780 --> 01:46:08,219 nơi ở giữa không phải ở kết thúc rồi hãy xem thực tế là gì place where are in the middle not at the end then let's see actually what 1310 01:46:08,219 --> 01:46:12,420 xảy ra ở đây bằng dấu phẩy sau đó gọi hàm này bạn sẽ có happened in here with a comma then calling this function you will have 1311 01:46:12,420 --> 01:46:16,920 làm điều gì đó giống như bạn phải làm thể dục tinh thần như phong tục này uh to do something like you have to do mental gymnastics like this custom uh 1312 01:46:16,920 --> 01:46:22,500 hai và bây giờ bạn phải vượt qua đóng cửa như thế này được rồi và sau đó bạn two and now you have to pass your closure like this all right and then you 1313 01:46:22,500 --> 01:46:26,639 nói LHS và rhs say LHS and rhs 1314 01:46:26,639 --> 01:46:32,940 và sau đó bạn nói LHS cộng rhs và sau đó bạn phải vào đây và nói 20 và 30 and then you say LHS plus rhs and then you have to go in here and say 20 and 30 1315 01:46:32,940 --> 01:46:39,179 chẳng hạn được rồi nên tôi không biết về bạn nhưng mã này trông bẩn hơn nhiều for instance okay so I don't know about you but this code looks a lot dirtier to 1316 01:46:39,179 --> 01:46:44,159 tôi hơn nó nên như vậy bởi vì nó có một rất nhiều nhãn và nó giống như một me than it should be because it has a lot of labels and it is like it is a 1317 01:46:44,159 --> 01:46:51,000 chức năng hoặc đóng cửa trước những các giá trị được gửi tới đây và đối với tôi điều này function or a closure before these values being sent here and so to me this 1318 01:46:51,000 --> 01:46:54,719 Thành thật mà nói trông không được sạch sẽ cho lắm với bạn và tất nhiên bạn có thể làm được điều này doesn't look very clean to be honest with you and you can of course make this 1319 01:46:54,719 --> 01:46:58,619 bạn cũng có thể ngắn hơn một chút xóa mã mà bạn đã viết a little bit shorter as well you can remove that code that you've written in 1320 01:46:58,619 --> 01:47:03,600 ở đây và bạn có thể nói đô la không đô la không cộng một đô la rồi làm như thế here and you can say dollar zero dollar zero plus dollar one and then do it like 1321 01:47:03,600 --> 01:47:08,340 cái này và sau đó đi 20 30. vì vậy nó trở thành một dễ đọc hơn một chút nếu bạn làm điều này this and then go 20 30. so it becomes a little bit more readable if you do this 1322 01:47:08,340 --> 01:47:15,060 tuy nhiên nó vẫn không sạch sẽ như vậy có thể như vậy bạn cũng có thể đặt có lẽ however it's still not as clean as it can be so you can also put perhaps the 1323 01:47:15,060 --> 01:47:18,000 giá trị 10 ở đây chỉ để chứng minh rằng điều này thực sự hoạt động như value of 10 in here just to demonstrate that this is actually working as 1324 01:47:18,000 --> 01:47:22,980 dự đoán vậy bây giờ chắc là 60 được rồi Vì thế expected so now this should be 60 okay so 1325 01:47:22,980 --> 01:47:27,780 ừm đó là lý do tại sao tôi thực sự khuyên bạn nên tận dụng việc đóng cửa theo sau um that's why I really suggest that you take advantage of trailing closure 1326 01:47:27,780 --> 01:47:32,760 cú pháp trong Swift và thêm các phần đóng của bạn nếu bạn có một đối số kết thúc tại syntax in Swift and add your closures if you have a closure argument at the 1327 01:47:32,760 --> 01:47:38,880 tuyệt đối kết thúc danh sách đối số của bạn được rồi bây giờ chúng ta đã thấy cách chúng ta có thể vượt qua absolute end of your argument list okay now we've seen how we can pass uh 1328 01:47:38,880 --> 01:47:44,940 các nhà khai thác như thế này để đóng cửa tham số của hàm và nhưng như bạn operators like this to a closure parameter of a function and but as you 1329 01:47:44,940 --> 01:47:50,520 như bạn mong đợi vì tranh luận xin lỗi vì các toán tử là các hàm bình thường và as you'd expect since arguments sorry since operators are normal functions and 1330 01:47:50,520 --> 01:47:55,560 bạn cũng có thể chuyển các chức năng bình thường cho đóng cửa vì vậy chúng ta hãy nhìn vào một you can also pass normal functions to closures so let's have a look at an 1331 01:47:55,560 --> 01:48:00,000 ví dụ hãy tạo một hàm ở đây nó được gọi là cộng 10 2 và sau đó chúng ta nhận được một example let's create a function in here it's called add 10 2 and then we get a 1332 01:48:00,000 --> 01:48:04,980 giá trị của số nguyên và chúng tôi trả về một số nguyên và chúng tôi chỉ cần thêm 10 vào giá trị này value of integer and we return an integer and we just add 10 to this value 1333 01:48:04,980 --> 01:48:10,080 được rồi và sau đó chúng ta có thể có cái khác chức năng ở đây được gọi là lúc 22 và sau đó all right and then we can have another function in here called at 22 and then 1334 01:48:10,080 --> 01:48:15,179 chúng ta chỉ cần thêm 20 vào bất kỳ số nguyên nào tham số được truyền cho hàm của chúng tôi we just add 20 to whatever integer parameter that is passed to our function 1335 01:48:15,179 --> 01:48:21,780 bây giờ chúng ta có thể có một hàm trong ở đây gọi là phép cộng được rồi và now we can then have an a function in here called do addition all right and 1336 01:48:21,780 --> 01:48:27,659 sau đó nó nhận một giá trị và chúng tôi ở bên ngoài gọi nó lên và chúng tôi nói làm phép cộng then it takes a value and we externally call it on and we say do addition on 1337 01:48:27,659 --> 01:48:33,179 giá trị được rồi int và sau đó chúng tôi muốn có một chức năng value all right int and then we want to have a function that 1338 01:48:33,179 --> 01:48:37,380 về cơ bản lấy giá trị này và thực hiện một số phép cộng với nó và trả về một số nguyên basically takes this value and does some addition with it and returns an integer 1339 01:48:37,380 --> 01:48:42,060 được rồi vì vậy chúng tôi nói sử dụng một hàm bằng cách sử dụng chức năng và chức năng này sẽ mất okay so we say using a function using function and this function should take 1340 01:48:42,060 --> 01:48:46,679 một số nguyên làm đối số duy nhất của nó và nó sẽ trả về một số nguyên được rồi, thế là xong an integer as its only argument and it should return an integer okay so that's 1341 01:48:46,679 --> 01:48:50,520 vì vậy nó không nên lấy hai số nguyên về cơ bản đơn giản chỉ vì chúng tôi muốn vượt qua so it shouldn't take two integers basically simply because we want to pass 1342 01:48:50,520 --> 01:48:55,739 một trong những chức năng này chỉ có một số nguyên làm đầu vào cho việc đóng này one of these functions which has only one integer as its input to this closure 1343 01:48:55,739 --> 01:49:00,780 ở đây được rồi và chức năng của chúng tôi sẽ trả về một số nguyên hơn những gì nó đang diễn ra in here okay and our function should return an integer than what it's going 1344 01:49:00,780 --> 01:49:05,639 để làm trong nội bộ sẽ gọi điều đó hàm với giá trị này và trả về giá trị của nó to internally do is going to invoke that function with this value and return its 1345 01:49:05,639 --> 01:49:10,560 kết quả là kết quả của chức năng của chúng tôi, chúng tôi lẽ ra có thể viết lại ở đây nhưng nó result as the result of our function we could have written return in here but it 1346 01:49:10,560 --> 01:49:15,360 không cần thiết trong Swift hiện đại nhé bây giờ chúng ta hãy tiếp tục và gọi cái này nhé is not necessary in modern Swift okay now let's go ahead and invoke this let's 1347 01:49:15,360 --> 01:49:21,960 nói làm phép cộng và sau đó chúng tôi nói trên giá trị là 20 và ở đây sử dụng bạn có thể say do addition and then we say on the value of 20 and in here using you could 1348 01:49:21,960 --> 01:49:25,860 bạn có thể tưởng tượng rằng bạn có thể tạo một rào chắn đường mòn ở đây bạn có thể you could imagine that well you could create a trail enclosure in here you can 1349 01:49:25,860 --> 01:49:30,000 nhìn thấy và chúng tôi nói giá trị và chúng tôi có thể nói giá trị see and we say value and we could say value 1350 01:49:30,000 --> 01:49:34,739 cộng thêm 30 được rồi vậy chuyện gì sẽ xảy ra ở đây giá trị 20 này sẽ là plus 30 okay so what is going to happen in here is this value of 20 is going to 1351 01:49:34,739 --> 01:49:40,020 được chuyển đến đây để đóng cửa này và nó sẽ bằng 20 cộng 30. vậy hãy xem liệu be passed here to this closure and it's going to be 20 plus 30. so let's see if 1352 01:49:40,020 --> 01:49:43,560 Sân chơi Swift sẽ có thể phục hồi và bạn có thể thấy 20 cộng 30 là Swift playground is going to be able to recover and you can see 20 plus 30 is 1353 01:49:43,560 --> 01:49:51,060 50. bây giờ thay vì làm điều này thay vì chuyển cái này về cơ bản thành nội tuyến 50. now instead of doing this instead of passing this uh into basically an inline 1354 01:49:51,060 --> 01:49:56,460 kết thúc vấn đề này bằng cách sử dụng đối số bạn có thể như bạn đoán, hãy chuyển một tham chiếu đến bất kỳ closure to this using argument you can as you'd guess pass a reference to any 1355 01:49:56,460 --> 01:50:01,920 của các chức năng này có cùng và cả hai chức năng này đều giống nhau of these functions that has the same and they both these functions have the same 1356 01:50:01,920 --> 01:50:07,380 ừ tiêu đề hoặc định nghĩa là phần đóng này họ lấy một số nguyên làm đối số của họ um header or definition as this closure they take an integer as their argument 1357 01:50:07,380 --> 01:50:12,719 và họ trả về một số nguyên nên giả sử mà chúng ta nói thêm 10 vào and they return an integer so let's say that we say add 10 to 1358 01:50:12,719 --> 01:50:17,820 như thế này và bạn có thể thấy bây giờ nó là thế này chức năng nội bộ sẽ được thông qua like this and you can see now it's this function internally going to be passed 1359 01:50:17,820 --> 01:50:21,420 thông qua điều này nên chức năng này sẽ diễn ra là 10 2 và nó sẽ là through this so this function is going to be at 10 2 and it's going to be 1360 01:50:21,420 --> 01:50:26,340 được gọi với giá trị 20. 20 cộng 10 sẽ là 30, tức là lúc đó invoked with the value of 20. 20 plus 10 is going to be 30 which is which is then 1361 01:50:26,340 --> 01:50:31,440 được in ngay trên bảng điều khiển sân chơi của chúng tôi sau đó hãy sao chép cái này và vào đây và printed right to our playground console then let's copy this and go here and 1362 01:50:31,440 --> 01:50:37,679 sau đó chúng ta nói cộng làm lại phép cộng vào 20 nhưng thêm 22 là chức năng khác của chúng tôi then we say add do addition again on 20 but add 22 which is our other function 1363 01:50:37,679 --> 01:50:44,820 lên đây được rồi và sau đó chúng ta có giá trị trong số 40 được in ra màn hình bây giờ và cái này up here okay and then we have the value of 40 printed to the screen now and this 1364 01:50:44,820 --> 01:50:48,659 chức năng này hơi lạ một chút vì bạn có thể thấy ý tôi là thực ra họ không có gì lạ function is a little bit strange as you can see I mean not strange actually they 1365 01:50:48,659 --> 01:50:54,659 không có bên ngoài tên đối số vì vậy nếu bạn thay đổi tên đó và don't have external argument names so if you change that and 1366 01:50:54,659 --> 01:50:57,780 để giá trị thực sự là tên đối số bên ngoài thì bạn phải so that the value is actually the external argument name then you have to 1367 01:50:57,780 --> 01:51:02,040 thay đổi chữ ký quá khứ ở đây vậy thì chúng ta nên nói thêm 10 với change the signature past here as well so then we should say add 10 to with 1368 01:51:02,040 --> 01:51:08,659 giá trị và thêm 22 với giá trị vì vậy chỉ cần thực hiện chắc chắn rằng chữ ký chức năng của bạn là value and add 22 with value so just make sure that your function signatures are 1369 01:51:08,659 --> 01:51:15,179 về cơ bản là chữ ký đúng theo về cách bạn đã xác định các chức năng đó trong basically the right signature according to how you've defined those functions in 1370 01:51:15,179 --> 01:51:21,719 ở đây được rồi rất tốt tôi nghĩ thế này là đủ rồi here okay very good I think this suffices for uh 1371 01:51:21,719 --> 01:51:27,179 việc đóng cửa thực sự là việc đóng cửa giống như tôi đã làm đã đề cập đến loại đối số nội tuyến closures really closures are as I've mentioned uh kind of inline arguments 1372 01:51:27,179 --> 01:51:30,780 và thông thường bạn chuyển sang người khác chức năng and usually that you pass to another function 1373 01:51:30,780 --> 01:51:35,940 và bạn có thể Xác định các lần đóng cửa và bằng cách gán hàm cho một biến và and you can Define closures and by assigning a function to a variable and 1374 01:51:35,940 --> 01:51:39,960 sau đó bạn có thể chuyển biến đó xung quanh các chức năng khác cũng vậy then you can pass that variable around to other functions as well so 1375 01:51:39,960 --> 01:51:43,800 thực sự là khi các nhà phát triển Swift đang nói chuyện về việc đóng cửa họ chỉ đang nói chuyện really when as Swift developers talking about closures they're just talking 1376 01:51:43,800 --> 01:51:50,219 về các chức năng thẳng hàng nên chúng không có từ khóa funk trước chúng about functions that are in line so they don't have the funk keyword before them 1377 01:51:50,219 --> 01:51:54,900 vì vậy bất kỳ chức năng nào không có từ khóa thú vị đằng sau nó thực chất là một so any function that doesn't have the fun keyword behind it is in fact a 1378 01:51:54,900 --> 01:51:58,739 thay vào đó bạn có thể đóng cửa khá nhiều cứ nói thế là được closure instead you could pretty much just say that okay 1379 01:51:58,739 --> 01:52:03,480 tốt, bây giờ chúng tôi đã hoàn thành việc đóng cửa và chúng tôi bây giờ có thể chuyển sang nói về một good we're done now with closures and we can now move on to talking about a 1380 01:52:03,480 --> 01:52:09,360 nhiều thứ thú vị hơn trong Swift ừm cụ thể là các cấu trúc hẹn gặp bạn ở đó little bit more fun stuff in Swift um namely structures see you there 1381 01:52:09,360 --> 01:52:14,940 vậy là bây giờ chúng ta đã hoàn thành việc đóng cửa hoặc tại ít nhất bây giờ chúng ta hãy tiếp tục và bắt đầu so we're now done with closures or at least for now let's go ahead and start 1382 01:52:14,940 --> 01:52:19,260 nói về các cấu trúc tôi nghĩ từ điểm này trong khóa học chúng ta sẽ talking about structures I think from this point on in the course we're gonna 1383 01:52:19,260 --> 01:52:22,679 thực sự có một chút niềm vui hơn vì chúng ta đã nói về sự tuyệt đối actually have a little bit more fun since we've talked about the absolute 1384 01:52:22,679 --> 01:52:28,320 những điều cơ bản về Swift cho đến thời điểm này và bạn có thể tưởng tượng rằng những điều cơ bản không phải như vậy basics of Swift up to this point and you can imagine that the basics are not so 1385 01:52:28,320 --> 01:52:33,659 vui vẻ và ít nhất tôi nghĩ đối với tôi cá nhân tôi phần thú vị đã đến fun and I think for me at least personally personally the fun part comes 1386 01:52:33,659 --> 01:52:39,239 khi chúng ta có cấu trúc liệt kê uh các lớp giao thức mở rộng chung chung in when we have enumeration structures uh classes protocols extensions generics 1387 01:52:39,239 --> 01:52:43,920 tất cả những điều đó vậy hãy bắt đầu với điều đó Tôi sẽ đi vào đây và làm thôi all that so let's get started with that I'm going to go in here and let's do 1388 01:52:43,920 --> 01:52:50,040 lệnh n và xcode và hãy tạo một sân chơi trống và chúng tôi sẽ gọi command n and xcode and let's create a blank playground and we're going to call 1389 01:52:50,040 --> 01:52:55,380 cấu trúc của nó ổn cấu trúc một lần nữa một cảnh báo xin vui lòng bấm vào it structures okay structures again a warning please click 1390 01:52:55,380 --> 01:52:59,760 tạo ra cái này không phải bên trong cái khác sân chơi chỉ cần thay đổi cả nhóm create this not inside another playground just change both the group 1391 01:52:59,760 --> 01:53:06,119 và thư mục vào thư mục gốc của bạn hoặc tới không gian làm việc của bạn về cơ bản là ổn và sau đó and the folder to the root of your or to your workspace basically okay and then 1392 01:53:06,119 --> 01:53:09,420 chúng tôi nói tạo ra vì vậy chúng ta có cấu trúc và hãy nhập we say create so we have structures and let's import 1393 01:53:09,420 --> 01:53:15,540 Kem nền như thường lệ tôi sẽ loại bỏ của Explorer ở phía bên trái Foundation as usual I'm going to get rid of the Explorer to the left hand side 1394 01:53:15,540 --> 01:53:22,619 vì vậy cấu trúc trong Swift là một cách nhóm dữ liệu lại với nhau và đưa ra một số so structures in Swift are a way of grouping data together and giving some 1395 01:53:22,619 --> 01:53:28,139 loại cấu trúc tên trong Swift là các loại giá trị và có nghĩa là khi bạn sort of a name structures in Swift are value types and meaning that when you 1396 01:53:28,139 --> 01:53:33,659 gán một thể hiện của một cấu trúc cho một biến khác thì dữ liệu bên trong assign an instance of a structure to another variable then the data inside 1397 01:53:33,659 --> 01:53:38,100 cấu trúc đó được sao chép lại nên bạn thực sự không nhận được that structure gets copied over so you don't actually get 1398 01:53:38,100 --> 01:53:43,020 ừ, hiểu là bạn không có được điều tương tự tham chiếu sử dụng hai biến tôi biết điều đó um it get you don't get the same reference using two variables I know it 1399 01:53:43,020 --> 01:53:46,080 Ý tôi là điều này có thể hơi một chút khó hiểu đặc biệt là I mean this could be a little bit difficult to understand for especially 1400 01:53:46,080 --> 01:53:49,500 những người không quen với giá trị các loại từ ngôn ngữ lập trình khác those who are not familiar with value types from another programming language 1401 01:53:49,500 --> 01:53:53,880 nhưng đừng lo lắng về điều đó tôi sẽ giải thích nó tất cả sẽ sớm thôi vậy trước hết chúng ta hãy đi thôi but don't worry about it I'll explain it all soon so let's just first of all go 1402 01:53:53,880 --> 01:53:57,060 phía trước và tạo cấu trúc đầu tiên của chúng tôi chúng ta sẽ gọi người đó là được rồi ahead and create our first structure which we're going to call person okay 1403 01:53:57,060 --> 01:54:01,619 người có cấu trúc và ở đây khi bạn tạo một cấu trúc struct person and in here when you create a structure 1404 01:54:01,619 --> 01:54:06,300 sau đó bạn có thể đi và khởi tạo nó bạn có thể tạo một ví dụ về điều này you can then go and instantiate it so you can create an instance of this 1405 01:54:06,300 --> 01:54:11,580 người như let Foo là người được và bạn có thể thấy sau đó bạn thực hiện cú pháp này person such as let Foo is person okay and you can see then you do this syntax 1406 01:54:11,580 --> 01:54:15,659 ở đây có dấu ngoặc đơn và bên trong dấu ngoặc đơn này bạn sẽ in here with parenthesis and inside this parenthesis you would 1407 01:54:15,659 --> 01:54:20,880 cuối cùng vượt qua mọi lập luận rằng Người xây dựng cấu trúc này yêu cầu eventually pass any arguments that the Constructor of this structure requires 1408 01:54:20,880 --> 01:54:25,260 tại thời điểm này cấu trúc không có bất kỳ giá trị nào bên trong nó nên nó không at the moment the structure doesn't have any values inside it so it doesn't 1409 01:54:25,260 --> 01:54:29,340 chứa bất kỳ thuộc tính nào vì vậy đó là điều quan trọng là phải hiểu thuật ngữ contain any properties so that's important to understand the term 1410 01:54:29,340 --> 01:54:33,300 tài sản nó không có tài sản nào và chúng ta có thể tiếp tục và tạo ra property it doesn't have any property and we could go ahead and create 1411 01:54:33,300 --> 01:54:39,239 tài sản và cách để làm điều đó là sử dụng từ khóa cảnh let's hoặc VAR RM properties and the way to do that is using the let's or VAR RM scene keywords 1412 01:54:39,239 --> 01:54:44,340 ở đây để bạn có thể nói rằng chúng tôi có một hằng số ở đây gọi là gáy và nó in here so you could say we have a constant in here called nape and its 1413 01:54:44,340 --> 01:54:47,400 kiểu dữ liệu phải là chuỗi và tất cả đều là một đột nhiên bạn thấy sân chơi của bạn đang diễn ra data type should be string and all of a sudden you see your playground is going 1414 01:54:47,400 --> 01:54:51,540 báo lỗi cho bạn ở đây nếu bạn có cũng tự động chạy, đặc biệt là nó to give you an error in here if you have automatic running as well especially it 1415 01:54:51,540 --> 01:54:54,659 cho bạn biết rằng bạn đang thiếu một đối số được gọi là tên hãy hỏi nó tells you that you are missing an argument called name let's just ask it 1416 01:54:54,659 --> 01:54:58,560 để sửa nó cho chúng tôi và chúng tôi nói tên được rồi đó là một chuỗi và chúng ta nói Foo ở đây to fix it for us and we say name okay it's a string and we say Foo in here 1417 01:54:58,560 --> 01:55:04,020 được thôi, giống như có thuộc tính tên ở đây bạn có thể tạo một tài sản khác okay just like having the name property in here you can create another property 1418 01:55:04,020 --> 01:55:07,800 ví dụ được gọi là H và chúng ta có thể nói bây giờ bạn thấy sân chơi nó là một số nguyên for instance called H and we could say it is an integer now you see playground 1419 01:55:07,800 --> 01:55:11,460 sẽ cung cấp cho bạn một khu vực khác ở đây nói rằng bạn đang thiếu tuổi will give you another area in here saying that you're missing the age 1420 01:55:11,460 --> 01:55:16,520 tranh luận và chúng ta có thể yêu cầu nó sửa nó và nói H được rồi chúng ta nói 20 ở đây được không argument and we can ask it to fix it and says H okay then we say 20 in here okay 1421 01:55:16,520 --> 01:55:21,659 bây giờ bạn có thể thấy chúng tôi đã tạo một ví dụ về người có hai thuộc tính now you can see we've created an instance of person with two properties 1422 01:55:21,659 --> 01:55:28,500 tên và H được rồi bây giờ bạn có thể truy cập những thuộc tính này bằng cách sử dụng cái gì đó gọi là name and H all right now you can access these properties using something called 1423 01:55:28,500 --> 01:55:35,280 ký hiệu DOT nên nếu bạn vào đây và nói tên Foo chấm và đồ ăn.h giống như a DOT notation so if you go in here and say Foo dot name and food.h just like 1424 01:55:35,280 --> 01:55:39,900 đó và sân chơi Swift sẽ là có thể in và sử dụng kết quả của that and Swift playground is going to be able to print and consume the results of 1425 01:55:39,900 --> 01:55:43,020 những cái này và in chúng ra bàn điều khiển dưới dạng tuy nhiên bạn có thể thấy ở đây nếu bạn these and print them to the console as you can see in here however if you're 1426 01:55:43,020 --> 01:55:46,980 viết mã Swift thuần túy điều này sẽ làm cho vô nghĩa, về cơ bản bạn đang nói là đồ ăn writing pure Swift Code this will make no sense you're basically saying food's 1427 01:55:46,980 --> 01:55:52,199 tên nhưng bạn không làm gì với nó nhưng vì sân chơi Swift ngầm name but you're not doing anything with it but since Swift playground implicitly 1428 01:55:52,199 --> 01:55:56,940 tiêu thụ kết quả của tất cả các biến và tất cả dữ liệu trả về nó đang được in consumes the result of all variables and all return data it is being printed in 1429 01:55:56,940 --> 01:56:03,239 ở đây nhưng trong Swift thì có nhiều khả năng là như vậy bạn sẽ nói hãy đặt tên và tuổi là here but in Swift it is more likely that you would say let's name and and age is 1430 01:56:03,239 --> 01:56:09,060 tên của foo và sau đó cộng với thức ăn theo tuổi bên trong như một sợi dây hay gì đó được chứ foo's name and then plus food that's age inside like a string or something okay 1431 01:56:09,060 --> 01:56:12,719 nên tôi sẽ không viết tất cả những điều đó nhưng bạn hiểu ý tôi nên bạn phải làm vậy so I'm not going to write all of that but you you get my point so you have to 1432 01:56:12,719 --> 01:56:16,860 tiêu thụ nó theo cách khác nếu bạn không sử dụng sân chơi Swift nhưng chỉ cần biết consume it in another way if you're not using Swift playgrounds but just know 1433 01:56:16,860 --> 01:56:21,360 mà bạn có thể đi sâu vào bên trong cấu trúc sử dụng ký hiệu này that you can drill down inside a structure using this notation which is 1434 01:56:21,360 --> 01:56:24,780 được gọi là ký hiệu dấu chấm bạn chỉ cần đặt tên của biến trỏ đến called a dots notation you just put the name of the variable that points to 1435 01:56:24,780 --> 01:56:29,880 cấu trúc và bạn nói dấu chấm và sau đó bạn lấy tài sản ra được rồi structure and you say dot and then you get the properties out okay 1436 01:56:29,880 --> 01:56:36,540 bây giờ bạn cũng có thể có tùy chỉnh Các nhà xây dựng cho các cấu trúc của bạn như bạn now you can also have custom Constructors for your structures as you 1437 01:56:36,540 --> 01:56:40,320 có thể thấy ở đây chúng tôi thực sự không có một hàm tạo và hàm tạo cho can see in here we didn't actually have a Constructor and the Constructor for 1438 01:56:40,320 --> 01:56:43,560 cấu trúc luôn được tạo ra bởi chính trình biên dịch và đây là một trong những structures is always created by the compiler itself and this is one of the 1439 01:56:43,560 --> 01:56:47,520 lý do nhiều người thích sử dụng cấu trúc nhanh chóng thay vì các lớp reasons a lot of people prefer to use structure as a swift rather than classes 1440 01:56:47,520 --> 01:56:52,860 đơn giản vì bạn không phải tạo Các nhà xây dựng cho họ Các nhà xây dựng là simply because you don't have to create Constructors for them Constructors are 1441 01:56:52,860 --> 01:56:58,080 được trình biên dịch ngầm tạo ra nên nếu bạn thêm một thuộc tính khác vào đây implicitly created by the compiler so if you add another property in here there 1442 01:56:58,080 --> 01:57:02,520 sẽ là một Trình xây dựng mới, vì vậy nó sẽ thay thế cái cũ chỉ có tên will be a new Constructor so which will replace the old one that had only name 1443 01:57:02,520 --> 01:57:06,480 và già đi với những lập luận mới trong đó như à hoặc tài sản mới trong đó nữa and age with the new arguments in it as well or the new property in it as well 1444 01:57:06,480 --> 01:57:10,739 được rồi, đó là một trong những thuộc tính của Cấu trúc Swift mà họ đã ngầm định okay so that's one of the properties of Swift structures that they have implicit 1445 01:57:10,739 --> 01:57:13,260 Các hàm tạo mà bạn không cần phải tạo bản thân bạn Constructors you don't have to create yourself 1446 01:57:13,260 --> 01:57:18,000 bây giờ nếu bạn muốn tạo một tùy chỉnh trình khởi tạo hoặc hàm tạo cho now if you do want to create a custom initializer or Constructor for your 1447 01:57:18,000 --> 01:57:21,119 cấu trúc bạn cũng có thể làm điều đó tôi sẽ chỉ cho bạn cách làm, vậy hãy tạo một structures you can also do that I'm going to show you how so let's create a 1448 01:57:21,119 --> 01:57:24,540 cấu trúc ở đây và chúng tôi nói Commodore máy tính ổn structure in here and we say Commodore computer okay 1449 01:57:24,540 --> 01:57:28,679 dành cho những bạn là học sinh cũ và đã làm việc với những người an ủi một trong những for those of you who are old schoolers and have worked with comforters one of 1450 01:57:28,679 --> 01:57:31,800 máy tính yêu thích của tôi nó thực sự là của tôi máy tính cá nhân đầu tiên tại my favorite computers it was actually my first personal personal computer at 1451 01:57:31,800 --> 01:57:36,119 Hàng hóa 64. được rồi và vì vậy chúng tôi tạo ra một máy tính thông thường và Commodore 64. okay and so we create a common computer and 1452 01:57:36,119 --> 01:57:42,119 chúng tôi nói hãy đặt tên nhé và tên của bạn là cái tên được cho là có gì đó we say let's name okay and your name is the name is supposed to be something 1453 01:57:42,119 --> 01:57:46,500 mà bạn chỉ định nó có thể giống như của tôi Commodore đáng yêu hay gì đó và sau đó chúng ta that you designate it could be like my lovely Commodore or whatever and then we 1454 01:57:46,500 --> 01:57:51,300 có một tài sản khác ở đây gọi là menu Factory Tôi luôn gặp khó khăn have another property in here called menu Factory I always have difficulty 1455 01:57:51,300 --> 01:57:56,099 viết và đánh vần nó và chúng tôi nói nó chuỗi bây giờ trong trường hợp này nếu ai đó writing and spelling it and we say it's the string now in this case if someone 1456 01:57:56,099 --> 01:57:59,940 muốn tiếp tục và tạo ra một ví dụ của máy tính Commodore nó sẽ wanted to go ahead and create an instance of commodore computer it would 1457 01:57:59,940 --> 01:58:04,440 có lẽ cứ cho là Commodore 64 là tương đương với máy tính màu và họ sẽ probably go let's say Commodore 64 is equal to color computer and they would 1458 01:58:04,440 --> 01:58:10,280 nói tên và sau đó họ sẽ nói của tôi hàng hóa say name and then they would say my commodore 1459 01:58:10,280 --> 01:58:16,320 và nhà sản xuất luôn luôn sẽ trở thành một Commodore được rồi, vậy nên trong and the manufacturer is always always going to be a Commodore okay so in 1460 01:58:16,320 --> 01:58:21,540 Commodore 64 có nhà sản xuất bìa và Commodore 128 cũng sẽ Commodore 64 has the manufacturer of cover and also Commodore 128 is going to 1461 01:58:21,540 --> 01:58:28,320 có màu của tôi là 128 được rồi nên cả hai những trường hợp này có nhà sản xuất là have a my color 128 okay so both of these instances have the manufacturer as 1462 01:58:28,320 --> 01:58:33,540 Commodore thì bạn có thể tự hỏi mình được không nếu bạn có một máy tính Commodore Commodore then you can ask yourself okay if you have a Commodore computer who 1463 01:58:33,540 --> 01:58:37,980 luôn có nhà sản xuất của nó bằng Commodore tại sao nên gọi trang web always has its manufacturer equal to Commodore why should the call site 1464 01:58:37,980 --> 01:58:43,139 có nghĩa là phần này vượt qua giá trị này và lặp đi lặp lại để bạn có thể tạo meaning this part pass this value over and over again so you could create a 1465 01:58:43,139 --> 01:58:48,420 Trình xây dựng luôn đặt giá trị này để bạn gửi Commodore, hãy tiếp tục và Constructor that always sets this value for you to Commodore let's go ahead and 1466 01:58:48,420 --> 01:58:53,340 hãy xem bạn có thể làm điều đó như thế nào vậy hãy tiếp tục và nói rằng chúng ta có một have a look at how you could do that so let's go ahead and say we have an 1467 01:58:53,340 --> 01:58:58,260 trình khởi tạo bạn có thể thấy ở đây được rồi bạn chỉ cần gõ vào nó chứ không vui vẻ gì initializer you can see in here okay so you just type in it not funk in it 1468 01:58:58,260 --> 01:59:03,239 ngoại trừ bạn chỉ cần gõ vào nó và nó ngầm trở thành một hàm thì vì except you just type in it and it implicitly becomes a function then since 1469 01:59:03,239 --> 01:59:06,719 đó là một chức năng thì bạn có danh sách đối số và sau đó là chức năng của bạn it is a function then you have your argument list and then your function 1470 01:59:06,719 --> 01:59:11,340 cơ thể như bạn có thể mong đợi ở đây bạn chỉ muốn bên gọi được thông qua body then as you as you can expect in here you just want the call side to pass 1471 01:59:11,340 --> 01:59:15,659 tên cho bạn nên bạn chỉ cần nói tên String nhưng bạn phát ra nhà sản xuất the name to you so you're just say name String but you emits the manufacturer 1472 01:59:15,659 --> 01:59:21,540 từ lúc khởi tạo nên bạn nói tự tên là tên được thôi và bạn cần phải from the initialization so you say self name is name all right and you need to 1473 01:59:21,540 --> 01:59:25,560 tiền tố tên này chỉ đơn giản là bởi vì nếu bạn nói tên bằng tên prefix this name which itself simply because if you say name is equal to name 1474 01:59:25,560 --> 01:59:29,940 nó chỉ nghĩ bạn thấy nó làm nổi bật tên nó nói tên là tên nó giống nhau it just thinks you see it highlights the name it says name is name it's the same 1475 01:59:29,940 --> 01:59:34,080 điều bạn thực sự không đề cập đến tên bên trong cấu trúc vì vậy bạn thing you're not actually referring to the name inside the structure so you 1476 01:59:34,080 --> 01:59:37,619 phải tự nói tên đó vậy Swift hiểu rằng bạn đang đề cập đến điều này have to say self that name so Swift understands you're referring to this 1477 01:59:37,619 --> 01:59:43,860 tên được gán giá trị này tranh luận được rồi bạn nói tự chấm name being assigned the value of this argument okay and then you say self dot 1478 01:59:43,860 --> 01:59:49,679 nhà sản xuất là Commodore nên bạn chính bạn hãy tự mình giao việc manufacturer is Commodore so you yourself take it upon yourself to assign 1479 01:59:49,679 --> 01:59:55,440 một giá trị cho tài sản này được rồi bạn có thể tiếp tục và nói 6 c64 là a value to this property okay then you can go ahead and say let's 6 c64 is 1480 01:59:55,440 --> 01:59:59,760 Máy tính Commodore và bạn có thể thấy lập luận duy nhất rằng trang web cuộc gọi phải Commodore computer and you can see the only argument that the call site has to 1481 01:59:59,760 --> 02:00:08,099 pass cho bạn là tên nên bạn nói c64 sau đó bạn có thể nói tên c64 và c64 tại dấu chấm pass to you is the name so you say c64 then you can say c64 name and c64 at dot 1482 02:00:08,099 --> 02:00:12,060 nhà sản xuất và các giá trị sẽ là chính xác như bạn mong đợi nên nó sẽ như vậy manufacturer and the values will be exactly as you'd expect them so it'll be 1483 02:00:12,060 --> 02:00:16,139 c64 và nhà sản xuất sẽ Commodore như bạn đã đặt nó bên trong c64 and the manufacturer will be Commodore as you've set it inside the 1484 02:00:16,139 --> 02:00:19,920 trình khởi tạo hoặc Trình xây dựng của cái này cấu trúc ổn initializer or the Constructor of this structure okay 1485 02:00:19,920 --> 02:00:24,540 thực ra bây giờ có nhiều cách khác làm điều đó vì vậy những gì bạn có thể đã làm now there are other ways of actually doing that so what you could have done 1486 02:00:24,540 --> 02:00:28,260 ở đây thay vì có một phong tục trình khởi tạo ở đây hoặc một Trình xây dựng mà bạn in here instead of having a custom initializer in here or a Constructor you 1487 02:00:28,260 --> 02:00:32,400 có thể đã bình luận điều này và anh ấy cho biết trong nhà sản xuất bằng Commodore could have commented this out and he said in manufacturer equal to Commodore 1488 02:00:32,400 --> 02:00:37,380 như thế này được rồi, điều này sẽ đạt được like this okay so this would have achieved the 1489 02:00:37,380 --> 02:00:42,000 kết quả chính xác là như vậy nên bạn không phải có một trình khởi tạo tùy chỉnh nếu bạn exact same result so you don't you don't have to have a custom initializer if you 1490 02:00:42,000 --> 02:00:47,040 muốn gán giá trị cho thuộc tính của bạn điều đó không thay đổi nhiều lắm, được rồi want to assign values to your properties that don't change pretty much okay so 1491 02:00:47,040 --> 02:00:51,480 xin hãy ghi nhớ điều đó để có một cách khác để làm điều đó just keep that in mind please so there's another way of doing that 1492 02:00:51,480 --> 02:00:54,659 được rồi bây giờ chúng ta đã xem xét điều đó, hãy có một okay now we've looked at that let's have a 1493 02:00:54,659 --> 02:00:58,440 nhìn vào một loại tài sản khác bạn có thể tạo bên trong cấu trúc của mình và look at another type of properties that you can create inside your structure and 1494 02:00:58,440 --> 02:01:02,280 chúng được gọi là thuộc tính tính toán và Tôi sẽ chỉ cho bạn Cú pháp của those are called computed properties and I'm going to show you the Syntax for 1495 02:01:02,280 --> 02:01:07,020 bây giờ hãy tiếp tục và tạo một cấu trúc mới vì vậy chúng tôi nói struct them now for that let's go ahead and create a new structure so we say struct 1496 02:01:07,020 --> 02:01:11,820 và không may là chúng tôi gọi đó là người thứ hai chúng tôi đã tiêu thụ hết người ở đây nên and we call it person two unfortunately we've already consumed person in here so 1497 02:01:11,820 --> 02:01:16,199 chúng ta không thể có cấu trúc khác gọi là người trừ khi chúng ta tiếp tục và bình luận we can't have another structure called person unless we go ahead and comment 1498 02:01:16,199 --> 02:01:18,840 điều này xảy ra nhưng chúng tôi sẽ không làm điều đó chúng ta hãy tạo ra một người nữa nhưng this out but we're not going to do that let's just create a person too but 1499 02:01:18,840 --> 02:01:22,920 xin vui lòng nếu bạn đang làm việc với sản xuất ứng dụng cấp độ xin vui lòng không làm điều này please if you're working with production level applications please don't do this 1500 02:01:22,920 --> 02:01:28,199 xin vui lòng không gọi cho cấu trúc của bạn hoặc lớp hai hoặc ba hoặc bốn trừ khi bạn please don't call your structures or classes two or three or four unless your 1501 02:01:28,199 --> 02:01:31,440 logic kinh doanh yêu cầu bạn làm điều đó được rồi business logic requires you to do that okay 1502 02:01:31,440 --> 02:01:34,560 trong tất cả những năm làm phần mềm của tôi sự phát triển tôi chưa bao giờ có which in all my years of software development I've never had the 1503 02:01:34,560 --> 02:01:38,219 yêu cầu gọi một cái gì đó là hai hoặc ba vậy requirement of calling something two or three so 1504 02:01:38,219 --> 02:01:41,760 ừm hãy ghi nhớ điều đó làm ơn đây là chỉ nhằm mục đích trình diễn um just keep that in mind please this is just for the purpose of demonstration in 1505 02:01:41,760 --> 02:01:48,300 sân chơi này được rồi nên chúng ta hãy tiếp tục và tạo ra một cấu trúc con người trong this playground okay so let's go ahead and create a person person structure in 1506 02:01:48,300 --> 02:01:51,659 ở đây với họ và tên vậy Tôi chỉ định nói tên thôi here with a first name and last name so I'm just going to say first name 1507 02:01:51,659 --> 02:01:56,400 là một đường thẳng và sau đó tôi sẽ sao chép cái này và tiếp tục và thay đổi lúc đầu thành is a straight and then I'm going to copy this and go ahead and change at first to 1508 02:01:56,400 --> 02:02:01,320 cuối cùng vì vậy chúng tôi có tên và họ bây giờ hãy nói rằng yêu cầu của bạn trong last so we have first name and last name now let's say that your requirement in 1509 02:02:01,320 --> 02:02:06,659 ở đây để tạo thuộc tính cho bạn cấu trúc người 2 gọi tên đầy đủ vậy here to create a property for your person 2 structure called full name so 1510 02:02:06,659 --> 02:02:10,980 tên đầy đủ này phải luôn bằng họ và tên có chữ a this full name should always be equal to the first name and the last name with a 1511 02:02:10,980 --> 02:02:16,080 khoảng trống ở giữa để bạn có thể làm gì là tiếp tục và tạo một bộ khởi tạo space in between it so what you could do is to go ahead and create an initializer 1512 02:02:16,080 --> 02:02:20,520 đối với người của bạn nữa và bạn có thể nói tên đầy đủ và bạn có thể thấy ở đây bạn for your person too and you could say full name and you can see in here you 1513 02:02:20,520 --> 02:02:26,460 không thể chỉ nói tên đầy đủ bằng họ và tên vì bạn can't just say full name is equal to first name and last name because you 1514 02:02:26,460 --> 02:02:32,219 thực sự sẽ gặp lỗi ở đây và bạn biết cú pháp này không hợp lệ nên hãy will get actually an error in here and you this this syntax is invalid so let's 1515 02:02:32,219 --> 02:02:35,159 thực sự có một cái nhìn ở đây không thể sử dụng họ của thành viên ví dụ trong actually have a look at here cannot use instance member last name within 1516 02:02:35,159 --> 02:02:39,900 trình khởi tạo thuộc tính vì tại điểm bạn gán giá trị này cho property initializer because at the point of you assigning this value to 1517 02:02:39,900 --> 02:02:44,699 họ và tên đầy đủ là không được biết đến mặc dù điều này có thể làm full name first name and last name are not known so even though this might make 1518 02:02:44,699 --> 02:02:49,080 chỉ cần nhìn vào nó nhưng Swift trình biên dịch không hoạt động theo cách đó nên bạn sense just looking at it but Swift compiler doesn't work that way so you 1519 02:02:49,080 --> 02:02:52,500 có thể bị cám dỗ để tiếp tục và nói được rồi tôi sẽ tạo một inch socializer trong could be tempted to go ahead and say okay I will create an inch socializer in 1520 02:02:52,500 --> 02:02:56,340 đây và tôi nói tên là một chuỗi cuối cùng here and I say first name is a string last 1521 02:02:56,340 --> 02:03:01,020 tên là một chuỗi nhưng tôi không muốn bạn cho tôi biết tên đầy đủ, tôi không thể hiểu được name is a string but I don't want you to pass me to full name I can't figure it 1522 02:03:01,020 --> 02:03:05,340 tôi tự mình ra ngoài nên bạn nói tên ô là tên tự họ là họ out on my own so you say cell first name is first name self last name is last 1523 02:03:05,340 --> 02:03:12,119 tên và tên đầy đủ của ô là một chuỗi bao gồm Ace một chuỗi khác name and cell full name is a string consisting of Ace another string which 1524 02:03:12,119 --> 02:03:15,780 là tên đầu tiên được truyền vào ở đây như một tham số và sau đó chúng ta sẽ is the first name which is passed in here as a parameter and then we will 1525 02:03:15,780 --> 02:03:21,239 có một khoảng trắng và sau đó là họ nên cái này thực sự là Swift Code hoàn toàn hợp lệ have a space and then last name so this actually is completely valid Swift Code 1526 02:03:21,239 --> 02:03:26,820 không có gì sai với nó cả, tôi sẽ tuy nhiên có một cách tốt hơn there's nothing wrong with it I would say however there is a better way of 1527 02:03:26,820 --> 02:03:31,560 làm điều đó và điều đó được sử dụng và đó là được gọi là thuộc tính máy tính, vậy bạn doing that and that is used and that is called computer properties so what you 1528 02:03:31,560 --> 02:03:34,920 có thể làm là loại bỏ hoàn toàn điều này trình khởi tạo ở đây could do is to completely remove this initializer in here 1529 02:03:34,920 --> 02:03:39,659 và sau đó thay đổi cái này thành VAR và sau đó biến nó thành một chức năng and then change this let's to a VAR and then make it a function 1530 02:03:39,659 --> 02:03:46,860 vậy đây là thuộc tính của máy tính khi bạn có một biến và bên trong và sau đó cho so this is a computer property when you have a variable and inside and then for 1531 02:03:46,860 --> 02:03:51,000 giá trị biến bạn thực sự có một hoạt động ở đây được rồi và ở đây bạn the variable value you actually have a function in here okay and in here you 1532 02:03:51,000 --> 02:03:56,820 chỉ có thể nói tên và khoảng trống họ nên bây giờ bạn thực sự could just say first name and space last name so now you actually 1533 02:03:56,820 --> 02:04:02,040 đã làm những gì chúng tôi muốn làm từ bắt đầu khi chúng tôi nói bằng với bạn thấy đấy did what we wanted to do from the beginning when we said equal to you see 1534 02:04:02,040 --> 02:04:06,239 chúng tôi cố gắng làm điều này nhưng nó không hiệu quả tất cả những gì bạn phải làm thực sự là tất cả những gì bạn có we try to do this but that didn't work all you have to do really all you have 1535 02:04:06,239 --> 02:04:10,199 vì vậy đây là điều chúng tôi cố gắng làm lúc đầu nhưng để làm được việc này bạn to so this is what we try to do at first but in order to get this to work you 1536 02:04:10,199 --> 02:04:13,800 phải nói trước VAR Xác định dữ liệu kiểu have to say first VAR Define the data type 1537 02:04:13,800 --> 02:04:18,179 để loại bỏ dấu bằng, hãy biến nó thành một chức năng và sau đó đặt logic vào đây to remove the equal sign make it a function and then put the logic in here 1538 02:04:18,179 --> 02:04:22,860 và đó sẽ là Swift Code hợp lệ nhé vì vậy bây giờ bạn có thể tiếp tục và tạo một and that will be valid Swift Code okay so you can now go ahead and create an 1539 02:04:22,860 --> 02:04:28,500 ví dụ của cấu trúc này giả sử một hãy để Foo bar là người thứ hai instance of this structure let's say a let Foo bar is person two 1540 02:04:28,500 --> 02:04:35,460 chúng tôi nói tên của bạn là Foo và họ tên là thanh như thế thì ta nói Foo we say pers first name is Foo and last name is bar like that then we say Foo 1541 02:04:35,460 --> 02:04:40,380 tên thanh và họ thanh thực phẩm và sau đó chúng ta có thể có quyền truy cập vào một tài sản bar first name and foodbar last name and then we can have access to a property 1542 02:04:40,380 --> 02:04:44,040 gọi tên đầy đủ giống như bạn có truy cập vào tên và họ bạn called full name just like you have access to first name and last name you 1543 02:04:44,040 --> 02:04:48,179 có thể thấy tên là thanh họ Foo thêm tên đầy đủ thuộc tính hoặc máy tính can see first name is Foo last names bar add full name property or computer 1544 02:04:48,179 --> 02:04:54,540 tài sản được đặt thành thanh không gian thức ăn được rồi và đây là cách các thuộc tính của máy tính hoạt động property is set to food space bar okay and this is how computer properties work 1545 02:04:54,540 --> 02:04:57,500 được rồi Hiện nay all right now 1546 02:04:57,500 --> 02:05:03,480 cấu trúc theo cách chúng được tạo ra là mà vốn dĩ họ không cho phép structures the way they're created is that they don't inherently allow 1547 02:05:03,480 --> 02:05:08,219 đột biến được rồi vậy hãy cùng có một ý tôi là hãy nhìn vào một ví dụ mutation right so let's let's have a look at an example every I mean 1548 02:05:08,219 --> 02:05:11,820 mọi thứ chúng tôi tạo ra cho đến nay đều đã được ý nghĩa bất biến là chúng ta chưa từng everything we've created so far has been immutable meaning that we haven't been 1549 02:05:11,820 --> 02:05:16,560 có thể thay đổi cấu trúc bên trong chúng tôi vừa khởi tạo những cấu trúc đó able to change the structure internally we've just instantiated those structures 1550 02:05:16,560 --> 02:05:20,040 và gán một số giá trị cho chúng và sau khi gán giá trị cho chúng, chúng ta and assigned some values to them and after assigning value to them we 1551 02:05:20,040 --> 02:05:25,380 thực sự không thể thay đổi những giá trị đó chúng ta không thể vào đây và nói tên c64 như couldn't actually change those values so we can't go in here and say c64 name as 1552 02:05:25,380 --> 02:05:30,239 ồ vậy điều này sẽ mang lại cho bạn một lỗi vì đây không phải là gán tất cả well so this is going to give you an error because this is not assign it all 1553 02:05:30,239 --> 02:05:35,040 đúng, bạn có thể thấy chúng tôi đã gặp lỗi trong được rồi, vậy làm cách nào để đảm bảo rằng chúng ta right you can see we got an error in here okay so how do we make sure that we 1554 02:05:35,040 --> 02:05:40,500 có thể tạo ra các cấu trúc có thể thay đổi vì vậy bạn thực sự có thể thay đổi chúng sau can create structures that are mutable so you can actually change them after 1555 02:05:40,500 --> 02:05:45,659 bạn tạo một phiên bản của chúng vậy hãy để tôi cho bạn xem một ví dụ về việc tạo một you create an instance of them so let me show you an example of creating a 1556 02:05:45,659 --> 02:05:50,699 chức năng có thể thay đổi cấu trúc được rồi vậy hãy tạo một chiếc ô tô ở đây ô tô function that can mutate a structure okay so let's create a car in here car 1557 02:05:50,699 --> 02:05:56,580 cấu trúc và sau đó chúng tôi nói tốc độ hiện tại là một số nguyên, hãy nói hiện tại structure and then we say current speed is in an integer let's just say current 1558 02:05:56,580 --> 02:06:01,500 tốc độ thì chúng ta có thể vượt qua 10 hoặc 20 nghĩa ví dụ 10 km/h speed then we can pass 10 or 20 meaning 10 kilometers an hour for instance 1559 02:06:01,500 --> 02:06:06,900 bây giờ nếu bạn muốn có một chức năng thì sao ở đây một ổ đĩa thú vị với một mục đích cụ thể now what if you want to have a function in here a funk drive with a specific 1560 02:06:06,900 --> 02:06:11,159 tốc độ được rồi và ở đây chúng ta có thể nói điều khiển speed okay and then in here we could say driving 1561 02:06:11,159 --> 02:06:16,440 nhưng điều chúng tôi muốn làm là thay đổi tốc độ hiện tại của chiếc xe này với tốc độ but what we want to do is to change the current speed of this car with the speed 1562 02:06:16,440 --> 02:06:20,940 được đưa ra bên trong chức năng ổ đĩa vì vậy nếu bạn nói tốc độ hiện tại that is given inside the drive function so if you say current speed current 1563 02:06:20,940 --> 02:06:25,739 tốc độ là tốc độ bạn có thể thấy bây giờ bạn ngay lập tức gặp lỗi ở đây nói speed is speed you can see now you immediately get an error in here saying 1564 02:06:25,739 --> 02:06:29,760 rằng bạn không thể làm điều đó nên nó nói không thể gán cho thuộc tính tốc độ hiện tại that you cannot do that so it says cannot assign to property current speed 1565 02:06:29,760 --> 02:06:35,580 và bởi vì nó là hằng số let vì vậy bạn có thể nói được rồi hãy khắc phục điều đó and because it is a let constant so you might say okay let's fix that 1566 02:06:35,580 --> 02:06:40,619 hãy đổi nó thành VAR thì điều này sẽ cũng không hoạt động vì bây giờ bạn có thể thấy let's change it to VAR then this will not work either because you can see now 1567 02:06:40,619 --> 02:06:45,960 bạn gặp một lỗi khác nói rằng không thể gán cho tài sản tự là bất biến nên you get another error saying cannot assign to property self is immutable so 1568 02:06:45,960 --> 02:06:50,880 gợi ý đó và đó là uh xcode sân chơi đang mang lại cho bạn điều đó Mark nói the suggestion that and that's uh xcode playgrounds is giving you it says Mark 1569 02:06:50,880 --> 02:06:56,460 phương pháp này bị biến đổi vì vậy hãy khắc phục điều đó và bạn thực sự có thể thấy gợi ý the method as mutating so let's fix that and you can see the suggestion actually 1570 02:06:56,460 --> 02:07:02,880 hoạt động nên chức năng này là tiền tố với từ khóa đột biến cho phép xe works so this function is prefix with the keyword of mutating allowing the car 1571 02:07:02,880 --> 02:07:08,699 trường hợp cần thay đổi và lý do đằng sau tất cả các môn thể dục tinh thần này là instance to be changed and the reason behind all of this mental gymnastics is 1572 02:07:08,699 --> 02:07:13,800 cấu trúc vốn dĩ là bất biến ý nghĩa và chúng cũng hẹn hò và that structures inherently are immutable meaning and and they're also date and 1573 02:07:13,800 --> 02:07:18,360 cũng có những loại giá trị có nghĩa là một khi bạn đã tạo một phiên bản của nó there are also value types meaning that once you've created an instance of it 1574 02:07:18,360 --> 02:07:21,780 nó đang nằm trong ngăn xếp và nó không nên thay đổi nhưng nếu bạn tạo một it's sitting in the stack and it shouldn't be changed but if you create a 1575 02:07:21,780 --> 02:07:26,099 một trường hợp đột biến rồi sau đó là một đột biến về cơ bản bạn đang uốn cong mutating instance then then a mutating function you're basically bending the 1576 02:07:26,099 --> 02:07:29,760 quy tắc về cách thức cấu trúc thực sự đang hoạt động và nó hoàn toàn hợp lệ Swift rules of how structures are actually working and it's completely valid Swift 1577 02:07:29,760 --> 02:07:33,980 cú pháp cũng vậy nên nó không có gì bất hợp pháp Nhưng syntax as well so it's nothing illegal but 1578 02:07:33,980 --> 02:07:39,719 Tôi nghĩ thực ra ý tôi là tất cả những năm tháng của tôi làm việc với Swift không thường xuyên lắm I think actually in I mean all my years of working with swift it is not so often 1579 02:07:39,719 --> 02:07:44,760 bạn muốn làm một cái gì đó như thế này và nhưng bên trong có rất nhiều lớp học you want to do something like this and but there are a lot of classes inside 1580 02:07:44,760 --> 02:07:49,679 Bản thân Swift có sự đột biến hoạt động nhưng thông thường khi nói đến Swift itself that have mutating functions but usually when it comes to 1581 02:07:49,679 --> 02:07:53,639 cấu trúc bạn không muốn thay đổi chúng nhưng đôi khi bạn có lý do chính đáng để structures you don't want to mutate them but sometimes you have valid reason to 1582 02:07:53,639 --> 02:07:58,260 làm điều đó được không vì vậy hãy tiếp tục và tạo một do that okay so let's go ahead and create an 1583 02:07:58,260 --> 02:08:03,599 chiếc xe bất biến bạn có thể nghĩ ổn nhưng điều đó có nghĩa là gì nhưng đây là một immutable car you may be thinking okay but what does that mean but this is a 1584 02:08:03,599 --> 02:08:08,219 chức năng đột biến tôi sẽ cho bạn xem ý tôi là hãy tạo một cá thể hoặc mutating function I'm going to show you what I mean let's create an instance or 1585 02:08:08,219 --> 02:08:12,119 một chiếc xe có thể thay đổi được gọi là xe bất biến và chúng ta sẽ nói đó là một ví dụ của a variable car called immutable car and we're going to say it's an instance of 1586 02:08:12,119 --> 02:08:16,679 xe và tốc độ hiện tại là 10. sau đó bạn có thể tiếp tục và nói chiếc xe bất biến car and this current speed is 10. then you can go ahead and say immutable car 1587 02:08:16,679 --> 02:08:22,500 và sau đó bạn có thể nói lái xe và với tốc độ 20. được rồi bạn có thể thấy and then you could say drive and with the speed of 20. all right you can see 1588 02:08:22,500 --> 02:08:26,940 bây giờ bạn sẽ có một công việc vặt ở đây đang nói rằng rất tiếc bạn đang gọi một now you're going to get an errand here saying that oops you're calling a 1589 02:08:26,940 --> 02:08:33,239 thành viên đột biến trên một giá trị bất biến hoặc biến và nó nói chiếc xe bất biến là một mutating member on an immutable value or variable and it says immutable car is a 1590 02:08:33,239 --> 02:08:38,400 hằng số chì nên điều xảy ra ở đây là rằng vì chiếc xe bất biến được cho phép lead constant so what happened here is that since immutable car is let 1591 02:08:38,400 --> 02:08:43,260 bạn không thể, bạn thực sự không thể gọi một hàm thay đổi giá trị bên trong you can't you can't actually call a function that changes the internal value 1592 02:08:43,260 --> 02:08:48,360 điều đó không đổi và đây là một trong sự khác biệt rất tinh tế giữa of that let constant and this is one of the very subtle differences between 1593 02:08:48,360 --> 02:08:53,159 hãy và VAR trong Swift nếu bạn nhớ khi chúng ta nói về các biến số ở let's and VAR in Swift if you remember when we talked about variables at the 1594 02:08:53,159 --> 02:08:55,679 sự bắt đầu tuyệt đối của khóa học này tôi đã đề cập rằng có một số nhỏ absolute beginning of this course I mentioned that there are some small 1595 02:08:55,679 --> 02:08:59,040 sự khác biệt giữa let's và bar chúng tôi không thể giải thích ngay bây giờ và đây là differences between let's and bar which we can't explain right now and this is 1596 02:08:59,040 --> 02:09:02,820 một trong những khác biệt đó là Swift là gì đang ở đây nói rằng được rồi bạn one of those differences what Swift is doing in here saying that okay you 1597 02:09:02,820 --> 02:09:07,020 tạo một hằng số let ở đây và bạn đang nói rằng nó bằng một create a let constant in here and you're saying that it is equal to an 1598 02:09:07,020 --> 02:09:11,699 ví dụ của một cấu trúc nhưng sau đó bạn tiếp tục và cố gắng thay đổi nó bằng cách instance of a structure but then you're going ahead and trying to change it by 1599 02:09:11,699 --> 02:09:16,560 gọi một hàm đột biến trên nó nếu chức năng này không bị thay đổi và chúng tôi calling a mutating function on it if this function wasn't mutating and we 1600 02:09:16,560 --> 02:09:20,699 không có mã này ở đây bạn sẽ có thể dễ dàng gọi nó bạn có thể thấy không didn't have this code in here you would be able to easily call it you can see no 1601 02:09:20,699 --> 02:09:24,840 vấn đề nhưng nếu chức năng này được đánh dấu khi đột biến bạn đang nói với Swift rằng problem but if this function is marked as mutating you're telling Swift that 1602 02:09:24,840 --> 02:09:29,460 chức năng này sẽ được thực hiện nội bộ thay đổi dữ liệu bên trong cấu trúc và this function is internally going to change the data inside the structure and 1603 02:09:29,460 --> 02:09:34,440 vì đây là hằng số let nên nó không phải được phép thay đổi bằng cách thay đổi since this is a let constant it is not allowed to change either so by changing 1604 02:09:34,440 --> 02:09:40,260 Ý tôi là bạn cũng không được phép làm điều này nên bạn không thể làm điều này và bạn không thể I mean you're not either allowed to do this so you can't do this and you can't 1605 02:09:40,260 --> 02:09:44,940 thay đổi nó trong nội bộ để cả hai những thứ này không hợp lệ được rồi, vậy đó là những gì change it internally either so both of these are invalid okay so that's what 1606 02:09:44,940 --> 02:09:49,739 hãy đại diện cho trường hợp này vậy chúng ta làm điều đó như thế nào, hãy bình luận nhé let's stands for in this case so how do we do that let's just comment 1607 02:09:49,739 --> 02:09:54,179 cái này ra và tiếp tục tạo ngay bây giờ một ví dụ có thể thay đổi của ô tô, chúng ta làm thế nào this out and go ahead and create now a mutable instance of car how do we do 1608 02:09:54,179 --> 02:09:59,340 tất nhiên là có một cú pháp từ và svar nó là một biến, nó có thể that well of course there's a syntax word and the svar it's a variable it can 1609 02:09:59,340 --> 02:10:05,580 thay đổi nên chúng ta nói xe có thể thay đổi là xe hơi với tốc độ hiện tại là 10. change so we say mutable car is a car with a current speed of 10. 1610 02:10:05,580 --> 02:10:11,099 sau đó bạn có thể tiếp tục và nói chiếc xe đó Xe chung then you can go ahead and say that car Mutual car 1611 02:10:11,099 --> 02:10:14,820 như thế này và lái xe với tốc độ 30. like this and drive with the speed of 30. 1612 02:10:14,820 --> 02:10:19,260 và sau đó bạn thấy dòng xe có thể thay đổi tốc độ thì bạn có thể thấy tốc độ hiện tại and then you see mutable car current speed then you can see the current speed 1613 02:10:19,260 --> 02:10:24,900 Sẽ đổi thành 30 ở đây nhé Vì thế is Gonna Change to 30 in here okay so 1614 02:10:24,900 --> 02:10:28,800 ừm điều chúng ta sẽ làm là hãy nhìn vào một chút sao chép um what we're going to do then is to have a look at a little bit of copying 1615 02:10:28,800 --> 02:10:33,480 giá trị và xem điều đó cũng ảnh hưởng như thế nào khả năng thay đổi lẫn nhau của chúng ta vì vậy hãy cứ values and seeing how that also affects our mutual mutability so let's just 1616 02:10:33,480 --> 02:10:38,159 tạm thời xóa mã này và nếu chúng ta tiếp tục và tạo một bản sao cho phép remove this code for now and if we go ahead and create a let copy 1617 02:10:38,159 --> 02:10:42,540 về điều này nên chúng tôi nói hãy nói rằng bản sao là chiếc xe bất biến vậy chúng ta đang làm gì of this so we say let's just say copy is immutable car so what what we're doing 1618 02:10:42,540 --> 02:10:48,360 ở đây là chúng ta đang lấy giá trị bên trong xe có thể thay đổi là một ví dụ của xe hơi in here is we're taking the value inside mutable car which is an instance of car 1619 02:10:48,360 --> 02:10:54,659 và chúng tôi đang gán nó cho một quyền mới hằng số được gọi là sao chép vì cấu trúc and we're assigning it to a new let constant called copy since structures 1620 02:10:54,659 --> 02:10:59,280 chỉ cần nhớ rằng cấu trúc trong Swift là các loại giá trị có nghĩa là nếu bạn just remember that structures in Swift are value types meaning that if you 1621 02:10:59,280 --> 02:11:02,900 gán một thể hiện của bất kỳ cấu trúc nào cho khác assign an instance of any structure to another 1622 02:11:02,900 --> 02:11:08,820 thay đổi dữ liệu nội bộ của đó cấu trúc sẽ được sao chép sang đây variable the internal data of that structure will be copied over to this 1623 02:11:08,820 --> 02:11:13,500 biến có nghĩa là bây giờ bạn có xe trùng lặp một trong xe có thể thay đổi variable meaning that now you have duplicate cars one is in the mutable car 1624 02:11:13,500 --> 02:11:18,239 và một cái khác đang được sao chép và họ có hoàn toàn không có mối liên hệ nào với nhau and another one is in copy and they have absolutely no connection to each other 1625 02:11:18,239 --> 02:11:22,560 hãy chứng minh điều đó và chúng tôi nói chiếc xe có thể thay đổi ở đây và chúng tôi nói hãy lái nó let's demonstrate that and we say mutable car in here and we say drive it 1626 02:11:22,560 --> 02:11:28,020 ở tốc độ 30. và sau đó chúng tôi nói Xe tương hỗ và tốc độ hiện tại và sau đó chúng tôi at the speed of 30. and then we say Mutual car and current speed and then we 1627 02:11:28,020 --> 02:11:33,360 nói sao chép tốc độ hiện tại bây giờ có lẽ bạn nghĩ ồ cả hai lẽ ra đều 30 nhưng bạn say copy current speed now you probably think oh they should both be 30 but you 1628 02:11:33,360 --> 02:11:37,440 có thể thấy rằng chiếc xe có thể thay đổi được thực sự bị đột biến bằng cách sử dụng ổ đĩa can see that the mutable car which was actually mutated using the drive 1629 02:11:37,440 --> 02:11:40,800 chức năng tuy nhiên tốc độ hiện tại của nó là 30 function it has the current speed of 30 however 1630 02:11:40,800 --> 02:11:46,260 bản sao có tốc độ hiện tại là 10 tại điểm nó đã được thực hiện hoặc the copy has the current speed of 10 at the point it was it was taken or 1631 02:11:46,260 --> 02:11:51,900 về cơ bản nó đã chiếm một bản sao của có thể thay đổi xe tại thời điểm này xe có thể thay đổi đã có basically it took over a copy of mutable car at this point mutable car had the 1632 02:11:51,900 --> 02:11:56,940 tốc độ hiện tại là 10 như bạn có thể mong đợi từ Trình xây dựng hoặc trình khởi tạo được current speed of 10 as you can expect from The Constructor or initializer okay 1633 02:11:56,940 --> 02:12:04,020 vì vậy hãy nhớ cấu trúc là loại giá trị khi bạn chỉ định một giá trị của let so remember structures are value types when you assign a value of a a let 1634 02:12:04,020 --> 02:12:08,460 ví dụ là hằng số hoặc một biến và nơi nó bằng với một thể hiện của constant for instance or a variable and where it is equal to an instance of 1635 02:12:08,460 --> 02:12:13,260 hướng dẫn cho một biến khác sau đó về cơ bản bạn đang nhận được một bản sao của cái đó instruction to another variable then you're basically getting a copy of that 1636 02:12:13,260 --> 02:12:17,880 cấu trúc và bạn có thể nghĩ ổn đó có phải là vì để cho được không structure and you might be thinking okay is that is that because of let okay 1637 02:12:17,880 --> 02:12:22,260 hãy kiểm tra xem hãy thay đổi điều này thành VAR và xem điều gì xảy ra ở đây bạn có thể thấy let's test that let's change this to VAR and see what happens in here you can see 1638 02:12:22,260 --> 02:12:27,300 nó thực sự không thay đổi bất cứ điều gì bởi gán chỉ đơn giản là gán một thể hiện it didn't really change anything by assigning simply assigning an instance 1639 02:12:27,300 --> 02:12:31,739 của một cấu trúc sang một biến khác cho dù đó là VAR hay để bạn thực hiện of a structure to another variable whether it's VAR or let you're making a 1640 02:12:31,739 --> 02:12:37,679 sao chép cái này và đặt nó vào đây nhé vì vậy đó là một điều rất rất quan trọng để copy of this and placing it in here okay so that's a very very important thing to 1641 02:12:37,679 --> 02:12:41,780 hiểu về cấu trúc Vì thế understand about structures so 1642 02:12:41,780 --> 02:12:49,079 cấu trúc trong Swift không thể phân lớp các cấu trúc khác được và phân lớp là structures in Swift cannot subclass other structures okay and subclassing is 1643 02:12:49,079 --> 02:12:53,219 một cái gì đó phát huy tác dụng khi chúng ta nói về các lớp học nhưng tôi đang đặt tên nó trong something that comes into play when we talk about classes but I'm naming it in 1644 02:12:53,219 --> 02:12:56,280 ở đây chúng ta chưa nói về nó nhưng Tôi đặt tên nó ở đây bởi vì tôi here we haven't talked about it yet but I'm naming it here because as I 1645 02:12:56,280 --> 02:12:59,579 đã đề cập ở phần giới thiệu về điều này tất nhiên tôi hy vọng bạn đã biết mentioned at the introduction to this course I expect you to already know 1646 02:12:59,579 --> 02:13:03,599 ngôn ngữ chương trình khác và rất có thể bạn có thể biết JavaScript hoặc python another program language and chances are you probably know JavaScript or python 1647 02:13:03,599 --> 02:13:07,860 hoặc Dart chẳng hạn hoặc rỉ sét và bạn có lẽ thoải mái với việc phân lớp or Dart for instance or rust and you are probably comfortable with subclassing 1648 02:13:07,860 --> 02:13:12,239 mặc dù rỉ sét thực sự không có phân lớp nó có loại khái niệm though rust doesn't really have subclasses it it has the concept kind of 1649 02:13:12,239 --> 02:13:18,179 thích các giao thức thì được nhưng Tôi chỉ muốn đề cập rằng Swift like protocols okay but I just want to mention that Swift 1650 02:13:18,179 --> 02:13:23,040 cấu trúc không thể có chức năng của phân lớp và tôi sẽ structures cannot have the functionality of subclassing and I'm gonna I'm gonna 1651 02:13:23,040 --> 02:13:27,540 giải thích rằng phân lớp khá nhiều hoạt động nhưng chúng ta sẽ đi sâu hơn vào explain that how subclassing pretty much works but we're going to go more into 1652 02:13:27,540 --> 02:13:32,340 chi tiết về phân lớp khi chúng tôi đến định nghĩa của các lớp trong Swift và details about subclassing when we get to the definition of classes in Swift and 1653 02:13:32,340 --> 02:13:37,560 điều đó sẽ xuất hiện sớm thôi, được rồi bây giờ chúng ta hãy tạo một cấu trúc rất tiếc và that is going to come up soon okay for now let's create a oops a struct and 1654 02:13:37,560 --> 02:13:41,460 chúng ta sẽ gọi nó là suy nghĩ sống và trong hàm init chúng ta sắp thực hiện we're going to call it living think and in the init function we're just going to 1655 02:13:41,460 --> 02:13:47,280 hãy nói rằng bây giờ tôi là một sinh vật sống có thể đang nghĩ ổn là một sinh vật sống say I'm a living thing all right now you may be thinking okay a living thing 1656 02:13:47,280 --> 02:13:51,540 có thể là một con vật chẳng hạn vì vậy chúng tôi tạo ra một cấu trúc và chúng tôi nói động vật và could be an animal for instance so we create a structure and we say animal and 1657 02:13:51,540 --> 02:13:55,079 bạn sẽ mong đợi nó có thể phân lớp sinh vật sống như thế này bạn you would expect it to be able to subclass living thing like this you 1658 02:13:55,079 --> 02:14:00,480 sẽ nói rằng một con vật thực sự là một sinh vật sống nhưng bạn không thể làm điều này, điều này không phải would say an animal is indeed a living thing but you can't do this this is not 1659 02:14:00,480 --> 02:14:06,179 một cú pháp uh Swift hợp lệ bạn có thể thấy điều này là sự kế thừa từ loại không có giao thức a valid uh Swift syntax you can see this is inheritance from non-protocol type 1660 02:14:06,179 --> 02:14:10,800 sinh vật sống vì vậy hãy ghi nhớ cấu trúc không thể kế thừa từ mỗi living thing so just keep in mind structures cannot inherit from each 1661 02:14:10,800 --> 02:14:16,380 cái khác trong Swift được rồi vì vậy hãy bình luận mã này và chúng tôi other in Swift okay so let's comment this code out and we 1662 02:14:16,380 --> 02:14:19,800 cứ để nó ở đó để lại mọi thứ vẫn là cú pháp đánh giá nên chúng ta chỉ có thể just leave it there leaving thing is still evaluative syntax so we could just 1663 02:14:19,800 --> 02:14:25,380 để nó ở đó nhé bây giờ trong Swift bạn cũng có thể có tùy chỉnh leave it there okay now in Swift you can also have custom 1664 02:14:25,380 --> 02:14:32,460 sao chép các cấu trúc và như chúng ta đã thấy khi bạn gán một giá trị bên trong một biến cho copying of structures and as we saw when you assign a value inside a variable to 1665 02:14:32,460 --> 02:14:38,040 như ở đây chúng tôi có chiếc xe có thể thay đổi được và bạn ký nó vào một bản sao để cố định like here we had mutable car and you sign it to a copy let constant the 1666 02:14:38,040 --> 02:14:43,500 toàn bộ nội dung của chiếc xe có thể thay đổi này đã được được sao chép sang biến này nhưng nếu entire contents of this mutable car was copied over to this variable but what if 1667 02:14:43,500 --> 02:14:47,280 bạn muốn có một phong tục nào đó logic trong khi sao chép một cái gì đó vào một you want to have some sort of a custom logic while copying over something to a 1668 02:14:47,280 --> 02:14:52,560 biến, bạn phải tạo ra nó hãy tự logic để tôi chỉ cho bạn cách variable well you have to create that logic yourself let me show you how let's 1669 02:14:52,560 --> 02:14:57,780 nói cấu trúc xe đạp chúng tôi nói nhà sản xuất được rồi và chúng tôi nói say struct bike we say manufacturer okay and we say 1670 02:14:57,780 --> 02:15:04,639 chuỗi và chúng tôi nói hãy để tốc độ hiện tại là số nguyên được rồi nếu bạn nói ở đây string and we say let current speed is integer all right now if you say in here 1671 02:15:04,639 --> 02:15:10,320 hãy đạp xe một là một chiếc xe đạp và chúng tôi có nhà sản xuất Harley let's bike one is a bike and we have a manufacturer of Harley 1672 02:15:10,320 --> 02:15:14,400 Davidson ở đây và chúng ta nói hãy nói tốc độ hiện tại là 20. nên không có gì Davidson in here and we say let's say the current speed is 20. so not nothing 1673 02:15:14,400 --> 02:15:20,460 bất hợp pháp và sau đó chúng tôi sẽ tạo ra một đạp xe số hai ở đây nên chúng ta nói hãy đạp xe nhé illegal and then we're going to create a bike two in here so we say let's bike 1674 02:15:20,460 --> 02:15:27,179 hai và sau đó bạn nói uh xe đạp một bây giờ bạn muốn làm gì ở đây bạn nói tốt two and then you say uh bike one now what you want to do in here you say well 1675 02:15:27,179 --> 02:15:32,639 Tôi muốn có một chiếc xe đạp nhưng tôi muốn thay đổi nó xin lỗi nhưng tôi muốn thay đổi I want to get bike one but I want to change its as sorry but I want to change 1676 02:15:32,639 --> 02:15:37,619 tốc độ của nó khi nó được giao cho biến này bạn không thể làm điều đó tại its speed when it is being assigned to this variable you can't do that at the 1677 02:15:37,619 --> 02:15:41,760 đúng lúc vì ngay cả khi bạn thay đổi điều này với VAR và nếu bạn nói Bike 2 moment right because even if you change this to VAR and if you say Bike 2 1678 02:15:41,760 --> 02:15:46,380 tốc độ hiện tại là 30 bạn không thể làm điều đó đơn giản vì tốc độ hiện tại bên trong current speed is 30 you can't do that simply because current speed inside the 1679 02:15:46,380 --> 02:15:51,960 xe đạp được chỉ định là bạn không thể bạn thay nó rồi đi nói được rồi tôi phải làm vậy bike is specified as let you can't change it you then go say okay I have to 1680 02:15:51,960 --> 02:15:55,619 thay đổi nó thành VAR thì bạn sẽ như vậy đúng, bạn không thể thay đổi nó thành VAR và change it to VAR then well you'd be right you can't change it to VAR and 1681 02:15:55,619 --> 02:15:59,219 mọi thứ sẽ hoạt động tốt nhưng hãy nhớ rằng bạn phải làm tất cả công việc này everything will just work fine but remember you have to do all of this work 1682 02:15:59,219 --> 02:16:04,440 đơn giản vì bạn có yêu cầu này ở đây để gán một chiếc xe đạp cho một chiếc xe đạp khác simply because you had this requirement in here to assign a bike to another bike 1683 02:16:04,440 --> 02:16:08,460 và thay đổi tốc độ hiện tại của nó một cách khác để làm điều này và nó and change its current speed there is another way of doing this and it's 1684 02:16:08,460 --> 02:16:12,599 thực sự được ưa thích hơn tôi sẽ nói với làm theo cách này mà tôi sẽ chỉ cho bạn actually more preferred I would say to do it this way that I'm going to show 1685 02:16:12,599 --> 02:16:16,739 bạn phải tạo một chức năng cho phép bạn làm điều đó để bạn có thể tiếp tục you is to create a function that allows you to do that so you could go ahead in 1686 02:16:16,739 --> 02:16:20,340 ở đây và nói tốt tôi có một chức năng và tôi sẽ gọi nó là sao chép nó here and and say well I have a function and I'm just going to call it copy it 1687 02:16:20,340 --> 02:16:24,719 không nhất thiết phải được gọi là sao chép, bạn có thể nói sao chép với hoặc bất cứ điều gì bạn muốn doesn't have to be called copied you can say copied with or whatever you want 1688 02:16:24,719 --> 02:16:30,060 được rồi bạn có thể nói sao chép và sau đó bạn nói tốc độ hiện tại nên bạn muốn thay đổi okay then you can say copy and then you say current speed so you want to change 1689 02:16:30,060 --> 02:16:34,019 tốc độ hiện tại vì vậy hãy coi nó như một đối số và sau đó chức năng của bạn có thể the current speed so take it in as an argument and then your function could 1690 02:16:34,019 --> 02:16:38,460 thực sự trả về một phiên bản của xe đạp chính nó thì bạn nói được thôi tôi tạo ra một chiếc xe đạp actually return an instance of bike itself then you say okay I create a bike 1691 02:16:38,460 --> 02:16:42,660 nhà sản xuất của nó là việc bán hàng nhà sản xuất vì hãy nhớ đây là một its manufacturer is the sales manufacturer because remember this is an 1692 02:16:42,660 --> 02:16:46,080 phương thức ví dụ có nghĩa là nó là thực sự hoạt động trên một phiên bản của instance method meaning that it is actually operating on an instance of 1693 02:16:46,080 --> 02:16:50,340 xe đạp để nó có quyền truy cập vào bản thân và nhà sản xuất và tốc độ hiện tại của nó bike itself so it has access to self and the manufacturer and its current speed 1694 02:16:50,340 --> 02:16:54,240 tốc độ hiện tại sẽ là đến từ chính cuộc tranh luận ở đây is going to be the current speed that is coming from the argument itself in here 1695 02:16:54,240 --> 02:16:57,599 được rồi vì vậy bây giờ bạn có cái đó bạn có thể đi okay so now that you have that you can go 1696 02:16:57,599 --> 02:17:01,859 tới địa điểm gọi ở đây và nói xe đạp một bản sao với tốc độ hiện tại là hãy ahead at call site in here and say bike one copy with the current speed of let's 1697 02:17:01,859 --> 02:17:06,300 nói 30. và sau đó nếu bạn thay đổi lại đối với lats bạn có thể thấy nó cũng hoạt động và say 30. and then if you change this back to lats you can see it works as well and 1698 02:17:06,300 --> 02:17:12,359 bằng hai tốc độ hiện tại bây giờ là ừ 30 và chúng ta cũng có thể nói xe đạp một by two current speed is now uh 30 and we could also say bike one 1699 02:17:12,359 --> 02:17:17,340 tốc độ hiện tại và bạn có thể thấy điều đó phải là 20. vì vậy đây là một cách current speed and you can see that should be 20. so this is one way of 1700 02:17:17,340 --> 02:17:22,200 tạo bản sao hoặc bản sao tùy chỉnh của bạn cấu trúc và thành thật mà nói với bạn creating copies or custom copies of your structures and to be honest with you 1701 02:17:22,200 --> 02:17:25,859 tôi không còn gì nhiều hơn nữa về các cấu trúc nghĩa là bạn chỉ cần hiểu khái niệm there's not much more to structures I mean it you have to just get the concept 1702 02:17:25,859 --> 02:17:30,719 về tính biến đổi và cấu trúc cũng như có khả năng tranh luận và of mutability and structures and also having the ability to have arguments and 1703 02:17:30,719 --> 02:17:34,859 xin lỗi vì có khả năng để có tài sản ở đây chúng ta đã nói về VAR sorry having the ability to have properties in here we talked about VAR 1704 02:17:34,859 --> 02:17:40,740 các thuộc tính cũng có thể biến đổi và chúng ta cũng đã nói về các thuộc tính được tính toán properties as well that can mutate and we also talked about computed properties 1705 02:17:40,740 --> 02:17:46,439 có thể trả về một giá trị bằng cách gán một hoạt động khá nhiều và đó là which can return a value by assigning a function pretty much to and that's 1706 02:17:46,439 --> 02:17:51,300 tranh luận xin lỗi về tài sản đó của cấu trúc nên không còn nhiều nữa argument sorry to that property of the structure so there's not so much more 1707 02:17:51,300 --> 02:17:55,500 vào các cấu trúc và tôi nghĩ chúng ta đã nói chuyện đủ về họ trong phần tiếp theo into structures and I think we've talked enough about them in the next section 1708 02:17:55,500 --> 02:17:59,219 chúng ta sẽ tiếp tục và nói về bảng liệt kê vì vậy hãy tạo we're going to go ahead and talk about enumerations so let's create the 1709 02:17:59,219 --> 02:18:03,960 bảng liệt kê tại Playground bây giờ vậy sân chơi lệnh n enumerations at Playground now so command n playground 1710 02:18:03,960 --> 02:18:08,160 và sân chơi trống và hãy gọi nó là sự liệt kê and blank playground and let's call it enumerations 1711 02:18:08,160 --> 02:18:13,500 và ở đây tôi sẽ nói nó là được tạo bên trong không gian làm việc chính, hãy and in here I'm going to say it is created inside the main workspace let's 1712 02:18:13,500 --> 02:18:17,160 thay đổi nhóm thành chính không gian làm việc ở đây và nhấn tạo change the group as well to the main workspace in here and press the create 1713 02:18:17,160 --> 02:18:22,080 nút được rồi sẽ thoát khỏi Explorer và giả sử nhập Foundation button okay gonna get rid of the Explorer and let's say import Foundation 1714 02:18:22,080 --> 02:18:29,040 được rồi bây giờ chúng ta hãy nói về liệt kê và ngâm là một trong những all right now let's talk then about enumerations and immersions are one of 1715 02:18:29,040 --> 02:18:32,880 các tính năng yêu thích của tôi về Swift và bất kỳ ngôn ngữ chương trình khác hỗ trợ nó my favorite features of Swift and any other program language that supports it 1716 02:18:32,880 --> 02:18:37,740 và tôi nghĩ thực ra gần như tất cả ngôn ngữ mà tôi đã làm việc ngoại trừ and I think actually almost all languages that I've worked with except 1717 02:18:37,740 --> 02:18:42,179 để lắp ráp tất nhiên hỗ trợ liệt kê hoặc một hình thức liệt kê I for assembly of course support enumerations or a form of enumerations I 1718 02:18:42,179 --> 02:18:46,620 nghĩa là Mục tiêu C nó C nó có C plus plus có đánh máy được không mean Objective C does it C does it have C plus plus does it typescript does it 1719 02:18:46,620 --> 02:18:51,059 JavaScript có phải là Python không? rỉ sét tất cả những ngôn ngữ này tôi đã làm việc JavaScript is it python does it Dart rust all these languages I've worked 1720 02:18:51,059 --> 02:18:55,800 có khái niệm về bảng liệt kê và ý tôi là điều đó rất tốt và with have the concept of enumerations and that's that's very good I mean and 1721 02:18:55,800 --> 02:18:59,219 họ có điểm liệt kê cho một ở một mức độ nhất định, chúng khác nhau they do have enumeration spot to a certain degree they differ from each 1722 02:18:59,219 --> 02:19:03,359 khác nên một số có trình độ cao hơn liệt kê như Swift tôi sẽ nói other so some have more advanced enumerations such as Swift I would say 1723 02:19:03,359 --> 02:19:07,439 Bảng liệt kê Swift là tiên tiến nhất Tôi đã nhìn thấy và sau sự rỉ sét đó Swift enumerations are the most advanced I've seen and after that rust 1724 02:19:07,439 --> 02:19:11,219 bảng liệt kê là số Advanced và sau đó chúng tôi cũng có JavaScript và enumerations are number Advanced and then we have also JavaScript and 1725 02:19:11,219 --> 02:19:16,019 bản đánh máy ở cùng cấp độ giống như hoạt hình phi tiêu nhưng cũng typescript which are at the same level kind of like Dart animations but also 1726 02:19:16,019 --> 02:19:21,120 Dart kém tiến bộ hơn trong việc hỗ trợ các tính năng khác nhau của liệt kê Dart is less advanced in supporting different features of enumerations 1727 02:19:21,120 --> 02:19:25,439 hoạt hình là gì ý tôi là tôi đã nói chuyện rồi bây giờ khá nhiều về bảng liệt kê nhưng what are animations I mean I've talked quite a bit now about enumerations but 1728 02:19:25,439 --> 02:19:30,059 họ là ai bảng liệt kê tốt là sự phân loại của what are they well enumerations are categorization of 1729 02:19:30,059 --> 02:19:36,420 các giá trị tương tự được đặt tên chẳng hạn như động vật mèo chó và thỏ similar values that are named such as animals cats dogs and rabbits 1730 02:19:36,420 --> 02:19:41,099 bạn có thể đặt chúng vào trong một bảng liệt kê bây giờ nếu tôi hỏi bạn và tôi nói you could put them inside an enumeration now if I for instance ask you and I said 1731 02:19:41,099 --> 02:19:46,200 hãy tạo một cấu trúc ở đây struct động vật và tôi đã nói xác định loại let's create a structure in here struct animal and I said define the type of 1732 02:19:46,200 --> 02:19:49,979 động vật ở đây bạn có thể sẽ nói Được rồi loại là một chuỗi animal in here you would probably say Okay type is a string 1733 02:19:49,979 --> 02:19:54,600 và tôi sẽ nói được vậy tôi có thể tạo một động vật và loại của nó là một chiếc xe đạp thì bạn and I would say okay so can I create an animal and its type is a bike then you 1734 02:19:54,600 --> 02:19:58,920 nói được vậy chúng ta nên làm gì hãy tiếp tục và tạo một trình khởi tạo trong say okay so what should we do should we go ahead and create an initializer in 1735 02:19:58,920 --> 02:20:04,740 ở đây có loại và nó nói nếu loại là một con thỏ here that takes the type and it says if type is a rabbit 1736 02:20:04,740 --> 02:20:09,899 hoặc gõ là Doc hoặc gõ or type is Doc or type 1737 02:20:09,899 --> 02:20:18,180 là mèo thì tự gõ là gõ nếu không thì bạn tạo một điều kiện tiên quyết is cat then self-type is type otherwise you create a preconditioned 1738 02:20:18,180 --> 02:20:21,540 sự thất bại rất tiếc nó không hoạt động giống như failure of oops it didn't work something like 1739 02:20:21,540 --> 02:20:27,660 đó là cú pháp hóa trị và ừ nó sẽ đi làm nhưng thực tế không phải vậy that so this is valence syntax and uh it is going to work but it is not so 1740 02:20:27,660 --> 02:20:31,740 rõ ràng ý tôi là rất nhiều trường hợp có lẽ mọi người thậm chí không nhìn thấy bạn obvious I mean a lot of cases it probably people don't even see your 1741 02:20:31,740 --> 02:20:35,100 mã nguồn nên họ phải loại đoán xem họ phải chuyển vào loại gì source code so they have to kind of guess what type they have to pass in 1742 02:20:35,100 --> 02:20:37,320 đây và đó là lý do chúng tôi có here and that is the reason we have 1743 02:20:37,320 --> 02:20:41,700 bảng liệt kê Đổi mới là phân loại các dữ liệu tương tự với nhau enumerations Innovations is the categorization of similar data together 1744 02:20:41,700 --> 02:20:45,600 bằng một cái tên vậy chúng ta hãy xem nó như thế nào by a name so let's have a look at how that 1745 02:20:45,600 --> 02:20:51,060 thực sự hoạt động, giả sử là một động vật enum được rồi và chúng ta có thể loại bỏ cấu trúc actually works let's say an enum animals okay and we can remove the structure 1746 02:20:51,060 --> 02:20:55,020 từ đây và bảng liệt kê này hãy cũng có sân chơi của chúng tôi như from here and this enumeration let's also have our playground as 1747 02:20:55,020 --> 02:20:59,460 tự động chạy và đó là động vật ở đây thì bạn có thể Xác định automatically running and it's animals in here then you can Define your 1748 02:20:59,460 --> 02:21:04,080 các loại động vật khác nhau mang lại cho chúng tên và cách để làm điều đó là sử dụng different types of animals giving them names and the way to do that is by using 1749 02:21:04,080 --> 02:21:10,620 cú pháp trường hợp ở đây hoặc từ khóa trường hợp sau đó bạn nói bạn không thể, tôi có một con mèo, tôi a case syntax in here or a case keyword then you say you can't I have a cat I 1750 02:21:10,620 --> 02:21:16,859 có một con chó và bây giờ tôi có một con thỏ khi Tôi nói tôi có, tôi thực sự không có ý đó have a dog and I have a rabbit now when I say I have I don't actually mean that 1751 02:21:16,859 --> 02:21:21,420 đây là những thuộc tính, ý tôi là đây là trường hợp liệt kê động vật này có these are properties I mean these are cases this animal's enumeration has 1752 02:21:21,420 --> 02:21:27,120 những trường hợp khác nhau và bạn cũng có thể bỏ qua trường hợp cho mỗi một trong những trường hợp này these various cases and you can also omit case for every one of these cases 1753 02:21:27,120 --> 02:21:31,020 và xóa nó đi và làm như thế này điều này cũng hoàn toàn hợp lệ and remove it and just do it like this as well this is also completely valid 1754 02:21:31,020 --> 02:21:37,380 Cú pháp Swift nên bạn không cần phải thêm tiền tố mọi trường hợp có từ khóa case nhưng một Swift syntax so you don't have to prefix every case with the case keyword but a 1755 02:21:37,380 --> 02:21:40,859 rất nhiều người làm điều đó và nó cho phép bạn cũng chuyển sang dòng tiếp theo, ý tôi là bạn lot of people do that and it allows you to also go to the next line I mean you 1756 02:21:40,859 --> 02:21:43,859 cũng có thể làm điều này nhưng có vẻ hơi thành thật mà nói với bạn thì hơi lạ nếu bạn can also do this but it looks a little bit strange to be honest with you if you 1757 02:21:43,859 --> 02:21:48,420 làm điều gì đó như thế này tôi chưa từng thấy hoạt hình trong Swift trong suốt những năm của tôi như do something like this I haven't seen animations in Swift in all my years like 1758 02:21:48,420 --> 02:21:53,340 Tôi đã viết như thế này viết như thế này hoặc nó được viết như thế I've written like this it's either written like this or it is written like 1759 02:21:53,340 --> 02:21:59,460 điều này thường ổn nhưng nó phụ thuộc vào về bạn và nhóm của bạn theo cách bạn muốn this usually okay but it kind of depends on you and your team how you want to 1760 02:21:59,460 --> 02:22:02,819 Xác định hình ảnh động của bạn, tôi nghĩ thế nào sẽ thực sự tốt nếu bạn và bạn Define your animations I think what would be really good if you and your 1761 02:22:02,819 --> 02:22:07,439 đội đã quyết định tổ chức một cuộc hội nghị về cách bạn muốn hoạt ảnh của mình sẽ như thế nào team decided on a convention of how you want your animations to be 1762 02:22:07,439 --> 02:22:11,399 tạo ra hoặc tất cả chúng đều có trường hợp trước họ hoặc bạn chỉ có một trường hợp created either all of them have case before them or you just have one case 1763 02:22:11,399 --> 02:22:17,220 đối với tất cả các trường hợp về cơ bản là ổn vì vậy bạn có thể đang nghĩ vậy thì được rồi bây giờ for all the cases basically okay so you may be thinking then okay now 1764 02:22:17,220 --> 02:22:21,060 rằng chúng tôi có cái này thì làm cách nào để tạo ra một ví dụ về những con vật này để chúng ta có thể that we have this how do we create an instance of these animals so we could 1765 02:22:21,060 --> 02:22:24,840 nói hãy để mèo là động vật chấm mèo như bạn có thể thấy ở đây bạn có tất cả những thứ này say let cat is animals dot cat as you can see in here you have all these 1766 02:22:24,840 --> 02:22:30,479 tài sản ở đây mèo chó thỏ v.v. giả sử là mèo và sau đó chúng ta có thể in nó properties in here cat dog rabbit Etc let's say cat and then we can print it 1767 02:22:30,479 --> 02:22:34,439 ra đây tới bảng điều khiển sân chơi và bạn có thể thấy nó chỉ nói mèo bạn có thể out here to the playground console and you can see it just says cat you can 1768 02:22:34,439 --> 02:22:40,080 thay đổi cái này thành màu tối và bạn có thể thấy nó nói con chó ở đây mặc dù chúng ta phải change this to dark and you can see it says dog in here though we have to 1769 02:22:40,080 --> 02:22:44,819 thay đổi tên biến có thể là được rồi, đó là cách đơn giản nhất change the variable name probably as well okay so that's the simplest way of 1770 02:22:44,819 --> 02:22:50,580 tạo một thể hiện liệt kê ngay bây giờ bạn có thể so sánh các bảng liệt kê với if creating an instance of enumeration now you can compare enumerations with if 1771 02:22:50,580 --> 02:22:57,000 các tuyên bố vì vậy nếu chúng ta đi vào đây và chúng ta nói nếu mèo bằng động vật mèo thì statements so if we go in here and we say if cat is equal to animals cat then 1772 02:22:57,000 --> 02:23:04,819 đây là một con mèo và chúng ta có thể nói khác nếu mèo là động vật this is a cat and we can say else if cat is animals 1773 02:23:04,819 --> 02:23:11,819 động vật chấm chó đây là một con chó nếu không thì đây là animals dot dog this is a dog otherwise this is 1774 02:23:11,819 --> 02:23:16,020 cái gì khác cũng được và tất nhiên là bạn có thể tiếp tục ở đây bạn có thể nói khác nếu something else okay and of course you can continue here you can say else if 1775 02:23:16,020 --> 02:23:22,260 mèo là động vật chấm uh thỏ tuy nhiên trong ở đây bạn không thể nói khác nếu con mèo bằng cat is animals dot uh rabbits however in here you can't say else if cat is equal 1776 02:23:22,260 --> 02:23:26,520 đến ba và điều này sẽ không hoạt động vì 3 là số nguyên và cat là số to three and this just won't work because 3 is an integer and cat is an 1777 02:23:26,520 --> 02:23:31,620 ví dụ về động vật nên bạn không thể so sánh bạn có thể thấy nó nói không có instance of animals so you cannot compare you can see it says there's no 1778 02:23:31,620 --> 02:23:37,380 toán tử so sánh giữa động vật và số nguyên và lúc đó bạn sẽ nghĩ comparison operator between animals and integer and you would be thinking then 1779 02:23:37,380 --> 02:23:41,520 ồ có lẽ tôi nên đi tạo một cái và bạn có thể làm điều đó bạn có thể nói funk oh maybe I should go and create one and you could do that you could say funk 1780 02:23:41,520 --> 02:23:47,340 bình đẳng và vì vậy đây là một hệ nhị phân toán tử infix ở phía bên trái bạn equality and so this is an in binary infix operator on the left hand side you 1781 02:23:47,340 --> 02:23:53,280 có một con vật động vật và bên phải bên tay bạn có một số nguyên và bạn have an animal animals and on the right hand side you have an integer and you 1782 02:23:53,280 --> 02:23:58,160 trả về một Boolean và bạn có thể nói nếu bạn có thể nói bạn quay lại phía bên trái return a Boolean and you could say if you could say you return left hand side 1783 02:23:58,160 --> 02:24:04,920 bên trái bằng con mèo và bên phải cạnh tay bằng ba được rồi left hand side is equal to cat and right hand side equal to three okay so then 1784 02:24:04,920 --> 02:24:09,780 cái này trả về một Boolean và bây giờ bạn có thể thấy lỗi của bạn sẽ biến mất để bạn có thể this returns a Boolean and now you can see your error will go away so you could 1785 02:24:09,780 --> 02:24:13,380 làm điều gì đó điên rồ như thế trong Swift nhưng làm ơn đừng làm thế, ý tôi là tôi chỉ do something crazy like that in Swift but please don't do it I mean I'm just 1786 02:24:13,380 --> 02:24:18,000 chỉ cho bạn những cách khác nhau để làm nhiều điều nhưng điều này tôi chỉ muốn nói với bạn showing you different ways of doing things but this I just want to tell you 1787 02:24:18,000 --> 02:24:24,660 rằng điều này là không ổn khi so sánh một ví dụ của một enum với một số nguyên that this is not okay to compare an instance of a an enum with an integer 1788 02:24:24,660 --> 02:24:28,200 chẳng hạn được thôi tuy nhiên có một cách khác để làm for instance okay however there's another way of doing 1789 02:24:28,200 --> 02:24:31,859 cái này sử dụng giá trị thô của nó nhưng chúng tôi chưa đã nói về điều đó rồi nên chúng ta hãy thôi this using its raw value but we haven't talked about that yet so let's just 1790 02:24:31,859 --> 02:24:37,020 loại bỏ cái này và loại bỏ toàn bộ cái này nếu tuyên bố từ đây như vậy được rồi vì vậy chúng tôi remove this and remove this entire if statement from here like that okay so we 1791 02:24:37,020 --> 02:24:41,640 chỉ cần có một cái khác và bạn có thể thấy như bạn mong đợi tuyên bố này đang được thực thi just have an else and you can see as you expect this statement is being executed 1792 02:24:41,640 --> 02:24:46,500 đơn giản vì mèo thực chất là một ví dụ về động vật chấm mèo được rồi hoặc simply because cat is in fact an instance of animals dot cat all right or 1793 02:24:46,500 --> 02:24:50,880 một ví dụ về động vật khá ngang bằng mèo ổn an instance of animals rather equal to cat okay 1794 02:24:50,880 --> 02:24:55,080 bây giờ nếu báo cáo là một chút lạ ở chỗ bạn sẽ phải viết now if statements are a little bit strange in that you would have to write 1795 02:24:55,080 --> 02:24:58,800 khá nhiều mã nếu và sau đó nếu và sau đó bạn phải so sánh chúng với quite a lot of code if and then else if and then you have to compare them with 1796 02:24:58,800 --> 02:25:03,240 động vật, v.v., có một cách khác làm cái này cái kia là sử dụng một công tắc animals etc etc there's another way of doing this and that is using a switch 1797 02:25:03,240 --> 02:25:07,859 tuyên bố tôi sẽ chỉ cho bạn cách làm điều đó nếu bạn nói bật một phiên bản statement I'm going to show you how to do that if you say switch on an instance 1798 02:25:07,859 --> 02:25:13,080 của một bảng liệt kê thì ở đây bạn có thể nhận trợ giúp thực sự từ xcode để hoàn thành of an enumeration then in here you can get help actually from xcode to complete 1799 02:25:13,080 --> 02:25:16,920 nó dành cho bạn, bạn có thể thấy và bạn chỉ nhấn nút sửa và nó sẽ báo it for you you can see and you just press the fix button and it will tell 1800 02:25:16,920 --> 02:25:21,780 bạn được rồi tôi biết con mèo đó là một ví dụ về động vật và tôi biết động vật you that okay I know that cat is an instance of animals and I know animals 1801 02:25:21,780 --> 02:25:26,460 có mèo, chó và thỏ tôi sẽ gõ tất cả đều dành cho bạn để bạn có thể thấy điều đó has cat and dog and rabbit I will type it out all for you so you can see that 1802 02:25:26,460 --> 02:25:31,319 cú pháp là chữ hoa và sau đó là giá trị enum và sau đó bạn có thể nhập một số mã vào đây syntax is case and then the enum value and then you can type some code in here 1803 02:25:31,319 --> 02:25:35,580 và bạn có thể nói break có nghĩa là như vậy ngay khi nó đạt đến điểm đó bạn chỉ cần and you can say break meaning that as soon as it hits that point you just 1804 02:25:35,580 --> 02:25:39,960 thoát ra khỏi câu lệnh chuyển đổi này như được rồi vậy chúng ta hãy tiếp tục vào đây và break out of this switch statement like this okay so let's go ahead in here and 1805 02:25:39,960 --> 02:25:45,540 nói đây là một con mèo và đây là một con chó và đây là một con thỏ say this is a cat and this is a dog and this is a rabbit 1806 02:25:45,540 --> 02:25:50,580 được rồi, chúng tôi đã viết mã của mình và chúng tôi hy vọng dòng này sẽ được thực thi và all right so we've written our code and we expect this line to be executed and 1807 02:25:50,580 --> 02:25:55,439 nếu bạn tiếp tục vào đây và thay đổi giá trị của con mèo đối với con chó thì trường hợp này là if you go ahead in here and change the value of cat to a dog then this case is 1808 02:25:55,439 --> 02:25:59,040 sắp bị xử tử bạn sẽ sớm thấy thôi đây là DOT đúng không going to be executed you'll see soon this is a DOT right 1809 02:25:59,040 --> 02:26:03,720 vì vậy hãy đổi lại thành mèo một lần nữa đây là cách bạn thực hiện chuyển đổi so let's change it back to cat again so this is how you would do a switch 1810 02:26:03,720 --> 02:26:09,180 câu lệnh và sau đó có Cú pháp cho chuyển đổi câu lệnh mà bạn không có statement and then there's a Syntax for switch statements where you don't have 1811 02:26:09,180 --> 02:26:13,200 để chỉ định tất cả các trường hợp vì vậy nếu bạn không muốn chỉ rõ trường hợp của con thỏ bạn to specify all the cases so if you don't want to specify the case of rabbit you 1812 02:26:13,200 --> 02:26:16,080 cũng có thể làm điều đó chỉ cần loại bỏ nó nhưng bây giờ bạn sẽ gặp lỗi vì can also do that just remove it but you're going to get an error now as 1813 02:26:16,080 --> 02:26:21,000 bạn sẽ sớm thấy nó sẽ nói rằng bạn chưa bao gồm tất cả các trường hợp hợp lệ you'll see soon it'll say that you haven't covered all the valid cases it 1814 02:26:21,000 --> 02:26:25,740 nói rằng nó phải có ý nghĩa đầy đủ rằng bạn phải bao gồm tất cả các trường hợp nhưng nếu says it must be exhaustive meaning that you have to cover all the cases but if 1815 02:26:25,740 --> 02:26:29,640 bạn không muốn bao gồm tất cả các trường hợp có một cú pháp đặc biệt gọi là mặc định you don't want to cover all the cases there is a special syntax called default 1816 02:26:29,640 --> 02:26:34,500 vào đây và nói đây là cái gì khác tương tự như tuyên bố khác của chúng tôi in here and say this is something else which is similar to our else statement 1817 02:26:34,500 --> 02:26:39,600 đúng vậy hai cái này gần như giống nhau cái kia của chúng tôi cũng đang sử dụng switch, cái kia right so these two are pretty much the same our One is using a switch the other 1818 02:26:39,600 --> 02:26:45,060 một người đang sử dụng ừm và nếu và khác tuyên bố bây giờ one is using a um an if and else statement now 1819 02:26:45,060 --> 02:26:51,120 ồ có lẽ tôi nên nói với bạn điều đó đây thường không phải là một ý tưởng hay oh I probably I should tell you that this is usually not a good idea 1820 02:26:51,120 --> 02:26:56,880 chỉ định một mệnh đề mặc định một cách đơn giản bởi vì trong tương lai ý tôi là ừ chúng ta hãy specifying a default clause simply because in the future I mean uh let's 1821 02:26:56,880 --> 02:27:01,800 hãy để tôi thực sự chứng minh cho bạn thấy hãy tiếp tục và ở đây nói rằng bạn có một let me actually demonstrate to you let's go ahead and in here say that you have a 1822 02:27:01,800 --> 02:27:07,020 funk và bạn muốn nói mô tả động vật và sau đó bạn nói động vật funk and you want to say describe animal and then you say animal 1823 02:27:07,020 --> 02:27:13,500 thuộc loại động vật được rồi bạn vào đi ở đây và bạn nói mô tả động vật is of type animals okay then you go in here and you say describe animal 1824 02:27:13,500 --> 02:27:18,899 và hãy đổi công tắc thành uh từ a mèo với một con vật ở đây được thông qua and let's change the switch to uh from a cat to an animal in here which is passed 1825 02:27:18,899 --> 02:27:25,140 với chúng tôi thì chúng tôi nói mô tả động vật và chúng tôi chuyển mèo của chúng tôi sang đó nhé to us then we say describe animal and we pass our cats to it okay 1826 02:27:25,140 --> 02:27:29,580 ừm trong trường hợp của con mèo, chúng ta đang nói điều này chúng ta đang nói đến con mèo trong trường hợp con chó um in the case of cat we're saying this is a cat in the case of dog we're saying 1827 02:27:29,580 --> 02:27:33,060 rằng đây là một con chó và thực ra ở đây chúng ta không cần phải chuyển Cat cho nó, chúng ta có thể that this is a dog and in here actually we don't have to pass Cat to it we can 1828 02:27:33,060 --> 02:27:38,460 nói động vật chấm thỏ được rồi nếu chúng ta làm điều đó bạn có thể thấy nó nói say animals dot rabbits okay if we do that you can see it says 1829 02:27:38,460 --> 02:27:43,620 bây giờ đây là thứ khác nếu chúng ta đi thì sao phía trước và thêm một trường hợp khác vào đây và this is something else now what if we go ahead and add another case in here and 1830 02:27:43,620 --> 02:27:49,439 chúng tôi nói trường hợp Hedgehog tôi nghĩ đó là đánh vần như thế này bây giờ bạn có thể thấy chúng tôi we say case Hedgehog I think it's spelled like this now you can see our 1831 02:27:49,439 --> 02:27:54,899 chức năng vẫn nói đây là một cái gì đó khác vì vậy đối với mọi trường hợp của chúng tôi function is still saying this is something else so for every case of our 1832 02:27:54,899 --> 02:28:00,660 ừ động vật ở nơi nó không được xử lý không phải mèo hay chó mà nó nói đây là um animals where it is not handled it's neither cat or a dog it's saying this is 1833 02:28:00,660 --> 02:28:04,800 cái gì khác thì cái này có thể có tác dụng ví dụ này nhưng thường ở kích thước lớn hơn something else well this might work in this example but usually in larger 1834 02:28:04,800 --> 02:28:10,500 các ứng dụng khi bạn thêm một trường hợp enum đến hình ảnh động mà bạn muốn ở mọi nơi applications when you add a an enum case to your animations you want everywhere 1835 02:28:10,500 --> 02:28:15,240 nơi bạn có một câu lệnh chuyển đổi sang thực ra hãy giải quyết trường hợp đó được rồi where you have a switch statement to actually take care of that case okay so 1836 02:28:15,240 --> 02:28:19,200 hãy để tôi chỉ cho bạn cách nếu chúng ta loại bỏ cái này trường hợp từ đây nên chúng ta có con chó mèo và let me show you how if we remove this case from here so we have cat dog and 1837 02:28:19,200 --> 02:28:23,160 thỏ một lần nữa chúng ta vào đây và mang theo trường hợp của rabbit again we go in here and we bring the case of 1838 02:28:23,160 --> 02:28:30,420 với thỏ được rồi và chúng ta nói điều này, điều này là một con thỏ và chúng ta ổn và chúng ta có thể at rabbit okay and we say this uh this is a rabbit and we break okay and we can 1839 02:28:30,420 --> 02:28:34,200 thực sự lấy cái này ra chúng ta không cần phải có nó bên trong một chức năng nữa chúng ta actually take this out we don't have to have it inside a function anymore we 1840 02:28:34,200 --> 02:28:39,120 lấy nó ra được rồi nói vào ở đây chúng tôi nói đổi mèo nên chúng tôi có tất cả take it out all right and then say in here we say switch cats so we have all 1841 02:28:39,120 --> 02:28:43,080 các trường hợp được bảo hiểm hiện nay là chó mèo và thỏ bây giờ nếu một lập trình viên khác trong chúng tôi the cases covered now cat dog and rabbit now if another programmer inside our 1842 02:28:43,080 --> 02:28:47,220 nhóm tiếp tục và thêm một trường hợp Hedgehog bạn có thể xem câu lệnh if của chúng tôi team goes ahead and adds a case of Hedgehog you can see our if statement 1843 02:28:47,220 --> 02:28:51,660 vẫn hoạt động và bạn có thể đang nghĩ chà, câu lệnh if vẫn hoạt động still works and you might be thinking well the if statement still works it 1844 02:28:51,660 --> 02:28:57,060 chắc là tốt nhưng công tắc không hoạt động vì vậy nó không tốt tuy nhiên theo ý kiến ​​​​của tôi must be good but the switch doesn't work so it's not good however in my opinion 1845 02:28:57,060 --> 02:29:02,160 nơi bạn tiếp tục và thêm một trường hợp mới vào liệt kê bạn cũng cần phải luôn luôn where you go ahead and add a new case on enumeration you need to also always 1846 02:29:02,160 --> 02:29:08,340 đảm bảo rằng ở mọi nơi bạn đang xử lý một ví dụ về liệt kê đó bạn ensure that everywhere you're handling an instance of that enumeration you're 1847 02:29:08,340 --> 02:29:12,899 cũng đang quan tâm đến vụ án mới nếu câu lệnh không làm được điều đó thì nó không taking care of the new case as well the if statement doesn't do that it doesn't 1848 02:29:12,899 --> 02:29:17,160 thất bại vì nó chỉ đơn giản là làm so sánh tuy nhiên switch đang làm được nhiều hơn fail because it's simply doing comparison however switch is doing more 1849 02:29:17,160 --> 02:29:21,060 hơn thế nó đảm bảo rằng nếu bạn bật một bảng liệt kê rằng than that it's ensuring that if you're switching on an enumeration that the 1850 02:29:21,060 --> 02:29:24,660 trường hợp liệt kê phải đầy đủ có nghĩa là bạn phải bao gồm tất cả enumeration cases must be exhaustive meaning that you have to cover all the 1851 02:29:24,660 --> 02:29:31,500 trường hợp như vậy theo ý kiến ​​​​của tôi với tôi trải nghiệm nó hầu như luôn luôn như vậy cases so in in my opinion with my experience it is always almost always 1852 02:29:31,500 --> 02:29:36,420 tốt nhất để so sánh các bảng liệt kê bằng cách sử dụng chuyển đổi được rồi vì nó sẽ cho bạn biết best to compare enumerations using switch okay because it will tell you 1853 02:29:36,420 --> 02:29:40,680 ồ bây giờ bạn không thể sử dụng mã của mình bởi vì ai đó đã đi và thêm một cái mới that oh you can't upon your code now because someone has gone and added a new 1854 02:29:40,680 --> 02:29:44,880 trường hợp thông qua công tắc bạn phải xử lý việc đó vậy nên hãy xử lý Hedgehog case through the switch you have to handle that so let's handle Hedgehog in 1855 02:29:44,880 --> 02:29:50,580 ở đây và chúng tôi nói đây là một con nhím được rồi và chúng ta nghỉ ngơi here and we say this is a hedgehog okay and we break 1856 02:29:50,580 --> 02:29:55,620 vì vậy bây giờ bạn có thể thấy nó được xử lý và mặc dù đây vẫn là một con mèo nên điều này so now you can see it is handled and though this is still a cat so this 1857 02:29:55,620 --> 02:29:58,979 tuyên bố đang được gọi nhưng ít nhất chúng tôi đã xử lý trường hợp thêm một statement is being called but at least we've handled the case of adding a 1858 02:29:58,979 --> 02:30:03,540 nhím ở đây được chứ bây giờ chúng ta đã giải quyết xong việc đó hedgehog in here okay now now that we've taken care of that 1859 02:30:03,540 --> 02:30:07,740 hãy nói về phép liệt kê một chút Các khái niệm về liệt kê nâng cao hơn một chút let's talk about enumerations a little bit more advanced enumeration Concepts 1860 02:30:07,740 --> 02:30:13,200 và đó là bảng liệt kê với Associated giá trị hoạt ảnh ổn trong Swift có and that is enumerations with Associated values okay animations in Swift have the 1861 02:30:13,200 --> 02:30:16,260 khả năng có các giá trị liên kết một phi tiêu ví dụ như đối với những bạn đang ability to have Associated values a dart for instance for those of you who are 1862 02:30:16,260 --> 02:30:19,200 các nhà phát triển rung bạn có thể nghĩ Dart đó cũng có cái đó nhưng flutter developers you probably think that Dart also has that but 1863 02:30:19,200 --> 02:30:25,200 tiếc là nó không có và trong Dart liệt kê bạn tạo một enum và bạn unfortunately it doesn't and in Dart enumerations you create an enum and you 1864 02:30:25,200 --> 02:30:28,920 không thể biến nó thành một lớp gần như bằng cách thêm thuộc tính cho nó và sau đó bạn tạo can't make it a class almost by adding properties to it and then you create 1865 02:30:28,920 --> 02:30:32,880 trường hợp enum mã hóa cứng các giá trị của những thuộc tính đó và đó không thực sự là enum cases that hard code the values of those properties and that's not really 1866 02:30:32,880 --> 02:30:37,680 điều tương tự như có bảng liệt kê với các giá trị được liên kết như Swift và the same thing as having enumerations with Associated values like Swift and 1867 02:30:37,680 --> 02:30:42,060 rỉ sét một nửa vì như bạn sẽ sớm thấy bảng liệt kê trong Swift có thể có rust half because as you'll see soon enumerations in Swift can have 1868 02:30:42,060 --> 02:30:46,620 Các giá trị liên kết động được thêm vào lúc tạo một Associated values that are dynamically added at the time of creating the an 1869 02:30:46,620 --> 02:30:50,280 ví dụ về lời tường thuật đó được rồi chúng ta hãy ví dụ hãy nhìn vào một instance of that narration okay let's for instance have a look at an 1870 02:30:50,280 --> 02:30:53,520 tích hợp được gọi là phím tắt hoặc phím tắt integration called shortcuts or shortcuts 1871 02:30:53,520 --> 02:30:58,859 giả sử ở đây bạn muốn tạo ba phím tắt và một phím tắt được gọi let's say in here you want to create three shortcuts and one is called for 1872 02:30:58,859 --> 02:31:05,340 ví dụ một trường hợp Tệp hoặc thư mục được một cái khác là URL www và sau đó là một instance a case File or folder okay another one is a www URL and then a 1873 02:31:05,340 --> 02:31:08,760 lối tắt đến một bài hát vì vậy hãy nói như vậy bạn đang tạo một bảng liệt kê có thể shortcut to a song so let's say that you're creating an enumeration that can 1874 02:31:08,760 --> 02:31:13,979 cho phép người dùng thực hiện một phím tắt đến bất kỳ một trong những trường hợp này là một bài hát dành cho allow the user to do a shortcut to any one of these cases either a song for 1875 02:31:13,979 --> 02:31:18,899 ví dụ trên Spotify hoặc một địa chỉ trang web hoặc một tập tin hoặc thư mục instance on Spotify or a website address or a file or folder 1876 02:31:18,899 --> 02:31:23,280 bây giờ bạn tiếp tục như thế nào và làm điều đó như thế nào vậy bạn có nói được không thế này hãy nói nhé now how do you go ahead and do that how do you then say okay this let's say let 1877 02:31:23,280 --> 02:31:27,720 www.táo là phím tắt www.apple is shortcut 1878 02:31:27,720 --> 02:31:33,120 tới URL www nhưng làm cách nào để chúng tôi chỉ định điều đó điều này thực sự sẽ đến với Apple to www URL but how do we specify that this is actually going to go to Apple 1879 02:31:33,120 --> 02:31:38,720 được rồi, có lẽ bạn sẽ làm vậy nghĩ rằng được rồi tôi muốn thêm trường hợp all right then you you would probably think that okay I want to add case 1880 02:31:38,720 --> 02:31:43,439 www.apple.com hoặc thứ gì đó tương tự ồ nếu bạn phải làm điều đó thì bạn www.apple.com or something like that well if you had to do that then you 1881 02:31:43,439 --> 02:31:48,240 sẽ phải tạo ra một trường hợp cho mọi trang web trên thế giới và nó sẽ không hoạt động would have to create a case for every website in the world and that won't work 1882 02:31:48,240 --> 02:31:52,380 và đó là lý do chúng tôi có Các giá trị liên quan cho bảng liệt kê là and that is the reason we have Associated values for enumerations is 1883 02:31:52,380 --> 02:31:56,220 Nhanh và rỉ sét vậy chúng ta hãy tiếp tục vào đây và bạn nói tôi Swift and rust so let's go ahead in here and you say I 1884 02:31:56,220 --> 02:32:00,000 muốn thêm một số giá trị cho những người này bất cứ ai đang tạo một phiên bản của bất kỳ want to add some values to these guys whoever is creating an instance of any 1885 02:32:00,000 --> 02:32:03,660 trong những trường hợp này phải vượt qua một số giá trị với họ thì chúng tôi nói ví dụ ở đây of these cases has to pass some values to them then we say for instance here 1886 02:32:03,660 --> 02:32:09,240 đường dẫn là một URL bạn nhìn thấy ở đây được chứ vậy thì ở phía cuộc gọi chúng tôi đang tạo the path is a URL you see in here okay so then at the call side we're creating 1887 02:32:09,240 --> 02:32:14,880 một phiên bản của URL WWE này bạn phải chuyển cho nó một URL được rồi vì vậy chúng tôi nói hãy truy cập an instance of this WWE URL you have to pass it a URL okay so we say let's go to 1888 02:32:14,880 --> 02:32:19,859 đường dẫn và chúng tôi tạo một URL và ở đây chúng tôi nói đó là một chuỗi https và the path and we create a URL and in here we say it's a string of https and 1889 02:32:19,859 --> 02:32:24,540 apple.com và chúng tôi buộc phải nhanh chóng chưa nói về nhà điều hành này apple.com and we force on rapid we haven't talked about this operator yet 1890 02:32:24,540 --> 02:32:31,460 thực ra tôi nghĩ chúng ta đã nói về nó một lần ừm đây có phải là hậu tố đơn nhất không actually I think we talked about it once is um this is a unary suffix 1891 02:32:31,460 --> 02:32:35,760 toán tử mà chúng tôi thực sự đã thấy ví dụ trước đây operator which we've actually seen an example of before 1892 02:32:35,760 --> 02:32:40,800 được thôi khi chúng ta đang nói về các tùy chọn nhưng bạn thấy chúng ta chưa đi sâu okay when we're talking about optionals but you see we haven't gone into depth 1893 02:32:40,800 --> 02:32:46,380 và vẫn còn các lựa chọn nên hãy chấp nhận điều đó hiện tại đây là một URL được nhưng chúng tôi thì không and with options yet so just accept that this is a URL for now okay but we don't 1894 02:32:46,380 --> 02:32:50,100 phải biết chính xác cái này làm gì Tôi sẽ giải thích nó sớm khi chúng ta đi have to know exactly what this one does I'm going to explain it soon when we go 1895 02:32:50,100 --> 02:32:53,760 và nói về các lựa chọn được rồi, bây giờ bạn có thể thấy chúng tôi thực sự and talk about options all right so you can see now we actually 1896 02:32:53,760 --> 02:32:59,880 đã chuyển một giá trị cho một thể hiện của cái này uh trường hợp enum và bạn có thể làm điều tương tự passed a value to an instance of this uh enum case and you can do the same thing 1897 02:32:59,880 --> 02:33:05,040 đối với những thứ khác như tệp hoặc thư mục, chúng tôi có thể giả sử nó có đường dẫn đến một URL và nó có một for others like file or folder we could say it has a path to a URL and it has a 1898 02:33:05,040 --> 02:33:11,040 tên của chuỗi được rồi và chúng ta có thể nói một bài hát có một nghệ sĩ thuộc loại chuỗi và name of string okay and we could say a song has an artist a of type string and 1899 02:33:11,040 --> 02:33:16,200 tên bài hát thuộc loại chuỗi thì được rồi điều này tùy thuộc vào bạn, ý tôi là nó thực sự ổn a song name of type string all right so this is up to you I mean it's really up 1900 02:33:16,200 --> 02:33:20,819 theo trí tưởng tượng của bạn Những giá trị bạn muốn đã liên kết với các trường hợp enum của bạn to your imagination What values you want to have associated with your enum cases 1901 02:33:20,819 --> 02:33:25,500 được rồi bây giờ bạn sẽ nghĩ ổn thôi okay now you would be thinking okay now that 1902 02:33:25,500 --> 02:33:30,660 chúng ta có anh chàng này làm thế nào để chúng ta so sánh nó với like nếu có trường hợp nào xảy ra với bạn we have this guy how do we compare it with like if if there is a case in your 1903 02:33:30,660 --> 02:33:34,380 ứng dụng nơi bạn nhận được một bản sao của một liệt kê hoặc một ví dụ về điều này application where you get a copy of an enumeration or an instance of this 1904 02:33:34,380 --> 02:33:39,359 liệt kê nếu bạn muốn xem liệu đây là một bài hát hoặc một URL hoặc một tập tin hoặc enumeration if you want to see whether this is a song or a URL or a file or 1905 02:33:39,359 --> 02:33:44,399 thư mục bạn làm điều đó như thế nào vậy bạn sẽ có lẽ sẽ nói nếu ww apple bằng folder how do you do it so you would probably say of if ww apple is equal to 1906 02:33:44,399 --> 02:33:50,700 phím tắt dot dot URL và sau đó giả sử bạn chuyển URL này tới nó shortcut dot dot URL and then let's say you pass this URL to it 1907 02:33:50,700 --> 02:33:56,520 bùm thì hãy làm điều này được rồi để bạn có thể nghĩ ổn tôi có thể làm điều đó nhưng không có bạn boom then do this okay so you may be thinking okay I could do that but no you 1908 02:33:56,520 --> 02:34:01,439 thực sự không thể làm điều đó bạn không thể làm so sánh giữa một cá thể enum với can't really do that you can't do comparison between an enum instance with 1909 02:34:01,439 --> 02:34:04,920 giá trị kết hợp và giá trị khác trong vô số có cùng giá trị kết hợp associative value and another in immenses with the same associative value 1910 02:34:04,920 --> 02:34:09,479 bởi vì ngay khi bạn thêm Liên kết giá trị cho bảng liệt kê trong Swift bạn because as soon as you add Associated values to enumerations in Swift you 1911 02:34:09,479 --> 02:34:14,580 về cơ bản bạn cần xác định sự bình đẳng đối với bản liệt kê này thì có basically you need to Define equality for this enumeration yourself there is 1912 02:34:14,580 --> 02:34:19,260 theo mặc định không có sự bình đẳng nữa trong việc này trường hợp khi chúng tôi có động vật và có no equality by default anymore in this case when we had animals and there was 1913 02:34:19,260 --> 02:34:24,000 không có giá trị kết hợp nào chúng tôi có thể làm điều này bởi vì Swift thêm sự bình đẳng tiềm ẩn no associative values we could do this because Swift adds implicit equality 1914 02:34:24,000 --> 02:34:28,260 toán tử là một trung tố nhị phân toán tử để liệt kê không có operator which is a binary infix operator to enumerations with no 1915 02:34:28,260 --> 02:34:32,280 Các giá trị được liên kết theo mặc định nhưng càng sớm càng tốt vì hoạt ảnh của bạn có giá trị Liên kết Associated values by default but as soon as your animations have Associated value 1916 02:34:32,280 --> 02:34:35,760 Swift không biết cách so sánh chúng nữa vì đó không phải là sự so sánh Swift doesn't know how to compare them anymore because it's not the comparison 1917 02:34:35,760 --> 02:34:39,720 về trường hợp của họ nữa nhưng bạn thực sự phải tự mình xác định sự so sánh of their cases anymore but you actually have to define a comparison yourself 1918 02:34:39,720 --> 02:34:44,220 có lẽ bạn chỉ muốn so sánh tên trong trường hợp tập tin hoặc thư mục có thể bạn maybe you want to only compare the names in the case of file or folder maybe you 1919 02:34:44,220 --> 02:34:48,180 không quan tâm đến con đường có thể trong trường hợp của một bài hát mà bạn không quan tâm don't care about the path maybe in the case of a song you don't care about the 1920 02:34:48,180 --> 02:34:52,740 nghệ sĩ mà bạn chỉ muốn về cơ bản so sánh tên bài hát nên Swift không thể artist you just want to basically compare the song names so Swift can't 1921 02:34:52,740 --> 02:34:58,740 suy ra toán tử đẳng thức đó cho bạn vì vậy bạn không thể làm điều đó trừ khi bạn tiếp tục deduce that equality operator for you so you can't do that unless you go ahead 1922 02:34:58,740 --> 02:35:02,880 và bạn cứ tiếp tục và về cơ bản Xác định toán tử đẳng thức là một and you go ahead and and basically Define equality operator which is a 1923 02:35:02,880 --> 02:35:06,840 tiến bộ hơn một chút so với những gì chúng ta đang có sẽ đi vào ngay bây giờ vì vậy bạn muốn little bit more advanced than what we're going to go into right now so as you'd 1924 02:35:06,840 --> 02:35:12,479 đoán bạn có thể dựa vào chuyển đổi bạn bè của bạn tuyên bố vì vậy chúng tôi nói chuyển đổi dấu chấm Apple trong guess you can rely on your friend switch statement so we say switch dot Apple in 1925 02:35:12,479 --> 02:35:16,560 ở đây và chúng ta thực sự có thể yêu cầu Swift hãy hoàn thành việc này cho chúng tôi, bạn sẽ thấy ngay bây giờ here and we can actually ask Swift to complete this for us you'll see now 1926 02:35:16,560 --> 02:35:21,359 ở đây sẽ có một gợi ý nhỏ sửa chữa và bạn có thể thấy nó sẽ xuất hiện it'll be a little hint in here it says fix and you can see it will come up with 1927 02:35:21,359 --> 02:35:27,960 tất cả các trường hợp cho chúng tôi đều ổn, bây giờ tôi thường không thích định dạng mặc định all the cases for us okay now I usually don't like the default format that is 1928 02:35:27,960 --> 02:35:32,040 được tạo ở đây nhưng chúng ta có thể sử dụng nó cho bây giờ tôi sẽ chia nhỏ chúng ra created in here but we can use it for now I'm just going to break them down 1929 02:35:32,040 --> 02:35:37,200 thành những phần nhỏ hơn ở đây thành những phần nhỏ hơn các đoạn mã bây giờ ở đây chúng ta into smaller parts in here into smaller bits of pieces of code now in here we 1930 02:35:37,200 --> 02:35:42,000 có thể nói in đường dẫn in tên và sau đó nghỉ ngơi ở đây cũng được could say print the path print the name and then break okay in here as well 1931 02:35:42,000 --> 02:35:45,899 chúng ta sẽ nói in đường dẫn và sau đó nghỉ ngơi và sau đó chúng ta sẽ đến đây we're going to say print the path and then break and then here we're going to 1932 02:35:45,899 --> 02:35:51,359 nói đưa nghệ sĩ đến dấu hiệu dòng riêng của mình đặt tên vào dòng riêng của nó và sau đó in say take the artist to its own line sign name to its own line and then print the 1933 02:35:51,359 --> 02:35:55,920 nghệ sĩ rồi in tên bài hát rồi artist and then print the song name and then 1934 02:35:55,920 --> 02:36:00,000 phá vỡ như thế được rồi nên bây giờ chúng ta có thể thấy break like that all right so now we can see 1935 02:36:00,000 --> 02:36:05,580 rằng chúng ta sẽ đạt đến điểm này và nó nói rằng bạn là con đường của that we're going to hit this point and it says that you are the path of 1936 02:36:05,580 --> 02:36:10,680 URL này thực ra là apple.com được rồi và thực ra tôi nghĩ ở đây đúng vậy this URL is actually apple.com all right and actually I think in here yeah it was 1937 02:36:10,680 --> 02:36:14,460 cũng được gọi là đường dẫn nhưng ở đây thì không phải được gọi giống nhau chỉ để bạn called path as well but here it doesn't have to be called the same just so you 1938 02:36:14,460 --> 02:36:19,620 biết con đường này nó không nhất thiết phải như vậy bạn có thể nói để P được rồi điều quan trọng know this path it doesn't have to be so you could say let P okay the important 1939 02:36:19,620 --> 02:36:25,439 một phần là cái này bây giờ có một cách khác, bạn cũng có thể part is this one now there is another way uh you can also 1940 02:36:25,439 --> 02:36:29,939 xóa tên đối số để bạn có thể thấy ở đây nó nói có một tên đối số remove the argument names so you can see in here it says there's an argument name 1941 02:36:29,939 --> 02:36:34,800 đường dẫn và sau đó là đường dẫn hãy sao chép cái này và làm cho nó sạch hơn hãy sao chép cái này path and then it's a let path let's copy this and make it cleaner let's copy this 1942 02:36:34,800 --> 02:36:39,600 toàn bộ mọi thứ nên đây là những gì Swift gợi ý bạn làm như vậy nhưng thường là trong entire thing so this is what Swift suggests that you do but usually in 1943 02:36:39,600 --> 02:36:43,500 mã trong cơ sở mã hoặc ít nhất là mã Tôi đã làm việc với không ai làm được điều này được codes in code bases or at least the ones I've worked with no one does this okay 1944 02:36:43,500 --> 02:36:49,080 không ai nói đây là nghệ sĩ và sau đó nghệ sĩ hãy không ai làm điều đó cái gì no one says here's the artist and then let's artist no one does that what 1945 02:36:49,080 --> 02:36:53,939 thông thường mọi người làm là tiếp tục và xâu chuỗi và loại bỏ việc đặt tên đối số bên ngoài này usually people do is go ahead and chain and remove this external argument naming 1946 02:36:53,939 --> 02:36:59,040 ở đây và cứ để chúng ta vào đây được rồi, hãy xóa đường dẫn và xóa here and just leave the let's in here okay so remove the path and remove the 1947 02:36:59,040 --> 02:37:03,899 điều trước đó cũng ở đây và cái này và bạn sẽ thấy rằng điều này hoạt động chính xác previous thing in here as well and this and you will see that this works exactly 1948 02:37:03,899 --> 02:37:10,680 giống như cái kia được rồi ừ đó là một cách viết khác và the same as the other one all right so uh that's another way of writing it and 1949 02:37:10,680 --> 02:37:16,380 điều này cũng rất rất phổ biến trong Swift ừ cơ sở mã là thứ mà mọi người không thích what is also very very common in Swift uh code bases is that people don't like 1950 02:37:16,380 --> 02:37:20,939 cú pháp viết let trước mỗi tên đối số để bạn có thể sao chép the syntax of writing let's before every argument name either so you could copy 1951 02:37:20,939 --> 02:37:26,340 mã này bây giờ hãy làm sạch nó ngay cả sẽ dán nó vào đây và xóa tất cả this code now let's clean it up even more gonna paste it here and remove all 1952 02:37:26,340 --> 02:37:31,439 những cái này hãy được rồi vậy hãy để these let's okay so that let 1953 02:37:31,439 --> 02:37:36,660 cái này cũng vậy và cả những độ dài này từ đây và những gì chúng ta sẽ làm là this let as well and also these lengths from here and what we're going to do is 1954 02:37:36,660 --> 02:37:40,319 tiếp tục ngay sau loại trường hợp cho phép to go ahead right after the case type let 1955 02:37:40,319 --> 02:37:45,540 ngay sau loại trường hợp để sang phải sau trường hợp loại cho phép, vì vậy, hãy để như vậy right after the case type let right after the case type lets so this let is 1956 02:37:45,540 --> 02:37:49,200 sẽ được áp dụng cho tất cả những điều này tranh luận ở đây và bạn có thể thấy nó going to be applied to all of these arguments in here and you can see it 1957 02:37:49,200 --> 02:37:54,660 hoạt động chính xác theo cách tương tự như nó đã làm trong hai ví dụ còn lại mỗi ví dụ là works exactly the same way as it did in the other two examples every example is 1958 02:37:54,660 --> 02:38:00,479 sẽ trở nên ngắn hơn và gọn hơn hơn cái trước về cơ bản là ổn going to become shorter and more compact than the one before it basically okay 1959 02:38:00,479 --> 02:38:07,500 thực sự tốt bây giờ có một cái khác rất cách nhỏ gọn để giải nén các giá trị bên trong really good now there's another very compact way of unpacking values inside 1960 02:38:07,500 --> 02:38:12,000 trong các lần lặp có liên kết giá trị in iterations that have Associated values 1961 02:38:12,000 --> 02:38:15,780 bây giờ có hai giá trị trong câu của tôi nhưng tôi nghĩ bạn hiểu ý và điều đó now there was two values in my sentence but I think you get the point and that 1962 02:38:15,780 --> 02:38:21,180 đang sử dụng câu lệnh if rất hiếm trường hợp nếu bạn chỉ muốn xử lý một is using an if statement in very rare cases if you want to only handle a 1963 02:38:21,180 --> 02:38:26,880 trường hợp enum cụ thể, ví dụ như trong trường hợp này bạn muốn xem liệu dấu chấm này specific enum case uh for instance in this case you want to see if this dot 1964 02:38:26,880 --> 02:38:33,840 dot apple là một URL thực tế bạn có thể sử dụng câu lệnh if Case let bạn có thể nói if dot apple is an actual URL you could use a if Case let statement you could say if 1965 02:38:33,840 --> 02:38:37,140 trường hợp cho phép và thành thật mà nói với bạn trong tất cả Case let and to be honest with you in all my 1966 02:38:37,140 --> 02:38:41,700 nhiều năm làm Swift tôi vẫn hiểu điều này hầu như lần nào tôi cũng gõ sai years of doing Swift I still get this wrong almost every time I sometimes type 1967 02:38:41,700 --> 02:38:46,620 trường hợp if let và đôi khi trường hợp if một cái gì đó một cái gì đó và sau đó để nhưng if let case and sometimes if case something something and then let but the 1968 02:38:46,620 --> 02:38:53,460 cú pháp thực tế là nếu Case let all right và sau đó bạn nói trường hợp này là dot dot URL actual syntax is if Case let all right and then you say the case is dot dot URL 1969 02:38:53,460 --> 02:38:59,340 đó là trường hợp enum thực tế của bạn và sau đó bạn nói pass bằng với biến của bạn which is your actual enum case and then you say pass is equal to your variable 1970 02:38:59,340 --> 02:39:04,319 sau đó bạn có thể in ra quá khứ để bạn có thể thấy nó được in ở đây nên bạn có thể then you can print out the past so you can see it's printed in here so you can 1971 02:39:04,319 --> 02:39:08,580 ở đây rồi nói nó có thể là bất cứ thứ gì nếu không nó có thể là tập tin hoặc thư mục và sau đó in here then say it could be anything else it could be file or folder and then 1972 02:39:08,580 --> 02:39:14,399 bạn có thể nói đường dẫn và sau đó đặt tên được rồi bằng you could say path and then name all right equal to 1973 02:39:14,399 --> 02:39:18,660 trường hợp enum của bạn như thế này và bạn có thể thấy nó không được thực thi your enum case like this and you can see it is not executed 1974 02:39:18,660 --> 02:39:23,520 đơn giản vì.apple không phải là một ví dụ trường hợp enum của tập tin hoặc thư mục ở đây simply because.apple is not an instance of file or folder enum case in here 1975 02:39:23,520 --> 02:39:29,100 hãy đổi lại thành drop.url và sau đó chúng ta có thể tìm ra con đường thoát khỏi let's change it back then to drop.url and then we can grab the path out of 1976 02:39:29,100 --> 02:39:35,700 trường hợp biến này hoặc một ví dụ phím tắt ở đây được rồi this variable instance or a shortcut instance in here okay 1977 02:39:35,700 --> 02:39:42,660 bây giờ trong khi bạn đang làm việc với enums, bạn cũng có thể bỏ qua các giá trị bên trong enum now while you're working with enums you can also ignore values inside the enum 1978 02:39:42,660 --> 02:39:47,280 các trường hợp hãy để tôi chỉ cho bạn cách giả sử chúng ta tạo một phiên bản phím tắt mà chúng tôi nói cases let me show you how let's say we create a an instance of shortcut we say 1979 02:39:47,280 --> 02:39:52,260 không có em là một ví dụ của phím tắt theo một bài hát của một trong những nghệ sĩ yêu thích của tôi without you is an instance of shortcut to a song by one of my favorite artists 1980 02:39:52,260 --> 02:39:57,300 Bản giao hưởng X và tên bài hát được gọi không có em nên một trong những điều thực sự tốt Symphony X and the song name is called without you so one of the really good 1981 02:39:57,300 --> 02:40:01,920 các bài hát của Symphony X tôi rất khuyến khích rằng bạn xem nó và xin lỗi và lắng nghe songs of Symphony X I highly recommend that you watch it and sorry and listen 1982 02:40:01,920 --> 02:40:06,420 với nó nếu bạn muốn thì tôi thực sự không nghĩ rằng có một video ca nhạc trong đó to it if you want to I don't actually think there is a music video to it 1983 02:40:06,420 --> 02:40:11,520 thật không may, nhưng có thể có một trong những lời bài hát này, ừ, video âm nhạc có trên đó unfortunately uh but there may be one of these lyrics uh music videos to it on 1984 02:40:11,520 --> 02:40:14,760 YouTube vì vậy bây giờ chúng tôi không có bạn và chúng tôi muốn YouTube so now we have without you and we want 1985 02:40:14,760 --> 02:40:20,340 để so sánh nó nếu đó là một bài hát của ừm ví dụ như chỉ nhìn vào bài hát của nó to compare it if it's a song by um for instance only looking at its song 1986 02:40:20,340 --> 02:40:27,840 tên nên chúng tôi nói nếu uh trường hợp hãy để và đó là một bài hát và chúng tôi không muốn name so we say if uh case let and it is it a song and we don't want 1987 02:40:27,840 --> 02:40:31,680 thực ra chúng tôi không quan tâm đến nghệ sĩ của nó vì vậy chúng ta có thể bỏ qua nghệ sĩ bằng cách sử dụng actually we don't care about its artists so we can ignore the artist using an 1988 02:40:31,680 --> 02:40:35,880 nhấn mạnh ở đây nhưng chúng tôi chỉ quan tâm về tên bài hát và chúng tôi nói nếu điều đó underscore in here but we only care about the song name and we say if that 1989 02:40:35,880 --> 02:40:40,080 bằng với việc không có bạn ở đây sau đó chúng ta có thể lấy tên bài hát is equal to without you in here then we can grab the song name 1990 02:40:40,080 --> 02:40:46,080 được rồi, bạn có thể thấy nó nói không có bạn mà không thực sự sử dụng nghệ sĩ trong okay so you can see it's it says without you without actually using the artist in 1991 02:40:46,080 --> 02:40:49,800 ở đây bạn cũng có thể nói là nghệ sĩ và sau đó gõ nghệ sĩ vào đây và lấy here you could also say artist and then type the artist in here as well and grab 1992 02:40:49,800 --> 02:40:53,819 nghệ sĩ đó bạn có thể nói đó là một bản giao hưởng X nhưng nếu bạn muốn bỏ qua nghệ sĩ that artist you can say it's a Symphony X but if you want to ignore the artist 1993 02:40:53,819 --> 02:40:57,840 bạn chỉ có thể chuyển dấu gạch dưới ở đây được rồi you can just pass underscore in here okay 1994 02:40:57,840 --> 02:41:06,540 thực sự tốt bây giờ bạn cũng có thể có một báo cáo trường hợp và trường hợp chuyển đổi cho really good now you can also have a case statements and switching case for 1995 02:41:06,540 --> 02:41:11,520 enums với các giá trị liên kết có kiểu dữ liệu tương tự được rồi để tôi để tôi enums with Associated values that have similar data types okay let me let me 1996 02:41:11,520 --> 02:41:15,600 thực sự cho bạn thấy một ví dụ về nó hãy hãy tiếp tục và tạo một enum của một chiếc xe actually show you an example of it let's go ahead and create an enum of a vehicle 1997 02:41:15,600 --> 02:41:21,960 được rồi và chúng ta nói một cái là ô tô và mỗi chiếc xe đều có một nhà sản xuất loại all right and we say one is a car and every car has a manufacturer of type 1998 02:41:21,960 --> 02:41:27,540 chuỗi và một mô hình kiểu chuỗi và sau đó chúng tôi cũng có xe đạp và với string and a model of type string and then we have bikes as well and with 1999 02:41:27,540 --> 02:41:32,040 nhà sản xuất cũng vậy và như thế này nhưng đối với xe đạp thì không manufacturer as well and like this but for bikes we don't 2000 02:41:32,040 --> 02:41:36,840 muốn một mô hình, chúng tôi muốn một số nguyên được tạo ra theo năm được rồi, bây giờ đây là một bảng liệt kê bạn want a model we want a year made integer okay so this is an enumeration now you 2001 02:41:36,840 --> 02:41:42,420 có thể đang nghĩ ổn, hãy nói rằng bạn luôn có trường hợp kinh doanh này may be thinking okay let's say that you have this business case of uh every time 2002 02:41:42,420 --> 02:41:48,240 bạn truy cập vào một phiên bản của chiếc xe bạn có thể muốn lấy nhà sản xuất của nó vậy làm thế nào you access an instance of vehicle you may want to grab its manufacturer so how 2003 02:41:48,240 --> 02:41:53,340 bạn có làm điều đó không, chúng ta hãy tiếp tục và nói hãy để ô tô là phương tiện do you do that let's let's go ahead and say let car is vehicle 2004 02:41:53,340 --> 02:41:56,460 và chúng ta làm điều đó như thế nào, hãy nói xe.car and how do we do that let's say vehicle.car 2005 02:41:56,460 --> 02:42:01,800 đối với nhà sản xuất của nó, chúng tôi nói đó là một chiếc Tesla và đối với mẫu chúng tôi nói đó là mẫu X thì for its manufacturer we say it's a Tesla and for model we say it's model X then 2006 02:42:01,800 --> 02:42:08,220 chúng ta nói hãy đi xe đạp là một phương tiện xe đạp được chứ và nhà sản xuất của nó là Harley Davidson we say let's bike is a vehicle bike okay and its manufacturers Harley Davidson 2007 02:42:08,220 --> 02:42:13,500 và đó là bạn đời của bạn, giả sử là 1987 hoặc đại loại thế được thôi, chỉ cần làm thôi and it's your mate let's say 1987 or something like that okay just making 2008 02:42:13,500 --> 02:42:18,060 mọi thứ ở đây được rồi, bây giờ bạn thế nào lấy nhà sản xuất ra khỏi hai things up in here okay now how do you grab the manufacturer out of these two 2009 02:42:18,060 --> 02:42:22,439 giống như bạn có một chiếc ô tô và bạn có một chiếc xe đạp và bạn muốn nắm bắt các nhà sản xuất của họ like you have a car and you have a bike and you want to grab their manufacturers 2010 02:42:22,439 --> 02:42:26,399 bạn biết cả hai đều có một nhà sản xuất nhưng làm thế nào để bạn lấy được nó you know both of them have a manufacturer but how do you grab that 2011 02:42:26,399 --> 02:42:32,939 ồ bạn có thể tiếp tục và nói được rồi tôi đổi xe tôi sẽ để Swift giải nén well you could go ahead and say okay I switched the car I'll let Swift extract 2012 02:42:32,939 --> 02:42:39,780 thông tin này cho tôi cho tất cả trường hợp thì thêm cái này vào đây rồi bạn nói this information for me for all the cases then add this in here then you say 2013 02:42:39,780 --> 02:42:43,620 được rồi tôi có nhà sản xuất tôi sẽ tìm hiểu rằng chúng ta có thể có một câu lệnh let okay I have the manufacturer I will learn that we can have a let statement 2014 02:42:43,620 --> 02:42:47,280 ở đây và xóa tất cả những thứ này ở đây vì vậy chúng tôi có nhà sản xuất nhưng chúng tôi không có in here and remove all of this in here so we have the manufacturer we don't 2015 02:42:47,280 --> 02:42:50,720 quan tâm đến mô hình để nhấn mạnh ở đây bạn nói nhà sản xuất care about the model so underscoring here then you say manufacturer 2016 02:42:50,720 --> 02:42:55,260 nhà sản xuất và sau đó bạn phá vỡ và bạn làm điều tương tự cho xe đạp được bạn nói manufacturer and then you break and you do the same thing for bike okay you say 2017 02:42:55,260 --> 02:43:01,080 trường hợp hãy để nhà sản xuất ở ngay đó và năm đã khiến chúng ta phớt lờ và rồi ở đây case let manufacturer is right there and the year made we ignore and then in here 2018 02:43:01,080 --> 02:43:06,600 bạn nói nhà sản xuất và nghỉ ngơi được rồi đúng rồi đây là một công tắc trên xe you say manufacturer and break okay so this is a switch on the car all right 2019 02:43:06,600 --> 02:43:10,560 và bạn có thể thấy chúng tôi đã tóm được chiếc Tesla nhà sản xuất ra khỏi chiếc xe đó nhưng làm gì and you can see we grabbed the Tesla manufacturer out of that car but what do 2020 02:43:10,560 --> 02:43:14,160 chúng tôi làm với chiếc xe đạp ồ vâng chúng tôi phải làm vậy hãy tiếp tục và làm điều tương tự với xe đạp we do with the bike oh yeah we have to go ahead and do the same thing for bike 2021 02:43:14,160 --> 02:43:20,280 chúng ta tiếp tục vào đây và nói bật lên chiếc xe đạp và chúng tôi nói trong trường hợp này vì we go ahead in here and we say switch on the bike and we say in this case since 2022 02:43:20,280 --> 02:43:24,780 bạn thấy đấy, đó là một chiếc xe đạp, Harley Davidson giải nén thì bạn có thể thông minh và nói it's a bike you see Harley Davidson is extracted then you may be smart and say 2023 02:43:24,780 --> 02:43:28,200 được rồi Tôi xin lỗi và bạn có thể không thông minh đâu okay I'm sorry and not you may be smart you 2024 02:43:28,200 --> 02:43:32,460 thông minh nhưng bạn có thể cố gắng trở nên thông minh nói được thì tôi có thể tạo một hàm are smart but you might try to be smart to say okay then I can create a function 2025 02:43:32,460 --> 02:43:36,200 ngoài chuyện này thì tôi sẽ nói vui ừm out of this then I will say funk um 2026 02:43:36,200 --> 02:43:41,939 có được nhà sản xuất từ xe get manufacturer from vehicle 2027 02:43:41,939 --> 02:43:49,080 được rồi và loại xe và nó trả về một chuỗi và ở đây bạn có thể okay and vehicle of type vehicle and it returns a string and in here you could 2028 02:43:49,080 --> 02:43:54,240 chỉ cần nói trở lại nhà sản xuất và nhà sản xuất trả lại bạn just say return manufacturer and return manufacturer you 2029 02:43:54,240 --> 02:43:58,439 cũng có thể làm điều đó được, vậy nên đây là thực sự là một bước gần hơn để thực hiện điều này could do that as well okay so this is actually one step closer to making this 2030 02:43:58,439 --> 02:44:03,060 hữu ích hơn một chút và sau đó bạn có thể gọi được nhà sản xuất a little bit more usable and then you could call gets manufacturer 2031 02:44:03,060 --> 02:44:10,080 uh từ ô tô và sau đó được nhà sản xuất từ xe đạp cũng được thôi nên bạn có thể làm uh from car and then gets manufacturer from bike as well okay so you could do 2032 02:44:10,080 --> 02:44:14,819 điều đó cũng vậy nên bạn có được Tesla và sau đó Ối that as well so you get Tesla and then oops 2033 02:44:14,819 --> 02:44:19,260 chuyện gì đã xảy ra với chiếc xe đạp của chúng tôi nhà sản xuất nên là Harley Davidson what happened to our bike the manufacturer should be Harley Davidson 2034 02:44:19,260 --> 02:44:24,359 vậy nhà sản xuất ô tô nhà sản xuất xe đạp à vì chúng ta đang bật ô tô nên đây là so car manufacturer bike manufacturer oh because we're switching on car this is 2035 02:44:24,359 --> 02:44:28,260 rất rất tệ chúng ta nên bật xe ở đây được rồi, đó là xe địa phương very very bad we should switch on the vehicle in here okay which is a local 2036 02:44:28,260 --> 02:44:32,700 biến cho hàm thì chúng ta sẽ có được Tesla và chúng ta sẽ sớm có được Harley variable to the function then we get our Tesla and we should now soon get Harley 2037 02:44:32,700 --> 02:44:37,160 Davidson vậy đây là một bước nữa hướng tới việc có thể tái sử dụng nhiều hơn Davidson so this is this is another step towards having a more reusable 2038 02:44:37,160 --> 02:44:42,479 khai thác nhà sản xuất từ ​​​​của chúng tôi phương tiện những gì bạn có thể làm là di chuyển extraction of manufacturer from our vehicles what you could do is to move 2039 02:44:42,479 --> 02:44:48,000 cái này thực sự ở ngoài và đặt nó vào trong chính enum và thay vì chuyển đổi this actually out and place it inside the enum itself and instead of switching 2040 02:44:48,000 --> 02:44:53,040 trên một chiếc xe được thông qua như một chúng ta có thể loại bỏ cái này và nói rằng chúng ta on a vehicle that is passed as a function we can remove this and say we 2041 02:44:53,040 --> 02:44:58,200 hãy thay đổi bản thân và sau đó chúng ta đi ở đây và sau đó chúng ta có thể nói xe được switch ourself all right and then we go in here and then we can say car gets 2042 02:44:58,200 --> 02:45:04,560 nhà sản xuất được rồi và sau đó chúng ta có thể nói xe đạp được nhà sản xuất đúng manufacturer okay and then we could say bike gets manufacturer right 2043 02:45:04,560 --> 02:45:08,399 vậy thực ra đó là một bước nữa hướng tới việc có nó nhiều hơn một chút so that's one one more step actually towards having it a little bit more 2044 02:45:08,399 --> 02:45:12,960 Nhỏ gọn và có nó có ý nghĩa hơn vì vậy đó là một chiếc xe được sản xuất và mua có được Compact and having it make more sense so it's a car get manufacture and buy get 2045 02:45:12,960 --> 02:45:16,800 sản xuất bây giờ cả hai đều có chức năng tương tự tuy nhiên những gì bạn có thể làm manufacturing now both of them have the same function however what you could do 2046 02:45:16,800 --> 02:45:21,540 là có cái này như một thuộc tính được tính toán enum giống như cấu trúc có thể có is to have this as a computed property enums just like structures can have 2047 02:45:21,540 --> 02:45:28,319 thuộc tính được tính toán nên giả sử VAR và chúng tôi đổi nó thành nhà sản xuất và chúng tôi computed properties so let's say VAR and we change it to manufacturer and we 2048 02:45:28,319 --> 02:45:31,920 nói rằng nó trả về một chuỗi và bây giờ đột nhiên bạn không có say it returns a string and now all of a sudden you don't have 2049 02:45:31,920 --> 02:45:36,060 gọi đây là một chức năng bạn có thể thực sự nói sản xuất giống như một to call this as a function you can actually say manufacture just like a 2050 02:45:36,060 --> 02:45:41,640 quyền sở hữu như thế này tốt bây giờ là một bước gần hơn để có property right like this good now it's one step closer to having 2051 02:45:41,640 --> 02:45:45,720 nó rất sạch sẽ còn một điều nữa mà chúng ta có thể làm để có được nó tốt hơn nữa it very clean there's one more thing that we can do to have it even better 2052 02:45:45,720 --> 02:45:50,220 và bạn có thể thấy rằng cả hai điều này trường hợp trường hợp hãy để xe trường hợp như xe đạp and that you can see that these both cases case let car case like bike 2053 02:45:50,220 --> 02:45:53,340 họ gần như đang làm điều tương tự so sánh họ đang trích xuất một they're pretty much doing the same comparison they're extracting a 2054 02:45:53,340 --> 02:45:57,359 nhà sản xuất và bỏ qua thứ hai cũng có giá trị nếu chúng ta có thể loại bỏ manufacturer and ignoring the second value well what if we could just remove 2055 02:45:57,359 --> 02:46:01,140 cái này và loại bỏ trường hợp này this and remove this case 2056 02:46:01,140 --> 02:46:06,540 và thay vào đó có dấu phẩy ở đây nên chúng tôi nói trong cả hai trường hợp là trường hợp của car và byte and have a comma here instead so we say in both cases the case of car and byte 2057 02:46:06,540 --> 02:46:10,439 chúng tôi sẽ trả lại nhà sản xuất và bạn có thể thấy đây là mã Swift hợp lệ we're returning the manufacturer and you can see that this is valid Swift code 2058 02:46:10,439 --> 02:46:16,260 và nó đang làm điều tương tự đúng vậy nếu bạn khớp mẫu trong and it is doing the exact same thing right so if you have pattern matching in 2059 02:46:16,260 --> 02:46:20,580 bảng liệt kê của bạn như thế này trong đó có hai trường hợp enum trở lên đều có cùng your enumerations like this where two enum cases or more are having the same 2060 02:46:20,580 --> 02:46:25,020 khớp mẫu bằng cách lấy một giá trị và nó không nhất thiết phải như vậy pattern matching by grabbing one value and it doesn't necessarily have to be 2061 02:46:25,020 --> 02:46:28,740 Thành thật mà nói với bạn điều này có thể được ví dụ có thể là trong trường hợp this to be honest with you it could it could for instance be in the case of 2062 02:46:28,740 --> 02:46:34,380 xe đạp và xin lỗi trong mô hình ở đây và bạn có thể bỏ qua cái này và thay vào đó hãy sử dụng bike and sorry in here model and you can ignore this one and instead use the 2063 02:46:34,380 --> 02:46:38,460 làm mẫu ở đây nên thực ra bạn có gọi họ giống nhau hãy nói model in here so actually you then have to call them the same thing let's say 2064 02:46:38,460 --> 02:46:45,420 Foo Foo và sau đó bạn trả lại Foo được rồi khớp mẫu Hoạt động cơ bản chỉ bằng cách Foo Foo and then you return Foo okay so pattern matching Works basically just by 2065 02:46:45,420 --> 02:46:50,280 khớp với các loại giá trị vì cả hai đây là những chuỗi và những thứ khác là matching the value types since both of these are strings and the other stuff is 2066 02:46:50,280 --> 02:46:54,240 bị bỏ qua thì bạn có thể sử dụng thực phẩm này nhưng thực ra chúng tôi đã phá mã vì being ignored then you can use this food but we actually broke the code because 2067 02:46:54,240 --> 02:46:58,080 thay vì nhà sản xuất ô tô, chúng tôi trả lại mẫu xe ở đây nhưng tôi instead of the car manufacturer we're returning the car model in here but I 2068 02:46:58,080 --> 02:47:01,319 chỉ muốn chứng minh cho nó thấy không nhất thiết phải ở cùng một nơi just wanted to demonstrate to it doesn't necessarily have to be at the same place 2069 02:47:01,319 --> 02:47:05,340 vì vậy nó không nhất thiết phải như vậy giống nhau ở giá trị đầu tiên của cả hai so it doesn't necessarily have to be like the same at first value of both 2070 02:47:05,340 --> 02:47:10,380 trường hợp được thì đây là một chiếc máy tính thuộc tính trên một bảng liệt kê cases okay so this is a computer property on an enumeration 2071 02:47:10,380 --> 02:47:16,620 và nó đang quay trở lại và nó đang thực hiện một khớp mẫu trên cả hai trường hợp và and it is returning and it's doing a pattern matching on the both cases and 2072 02:47:16,620 --> 02:47:20,580 nó không có báo cáo trường hợp riêng biệt ở đây được rồi it doesn't have separate case statements in here okay 2073 02:47:20,580 --> 02:47:26,160 thực sự tốt phần đó cũng đã xong rồi ngoài các bảng liệt kê với Associated really good that part's also done now apart from enumerations with Associated 2074 02:47:26,160 --> 02:47:31,200 giá trị bạn cũng có thể có bảng liệt kê với các giá trị thô và đây là một ví dụ về values you can also have enumeration with raw values and here's an example of 2075 02:47:31,200 --> 02:47:34,520 vậy hãy tiếp tục và nói enum gia đình that so let's go ahead and say enum family 2076 02:47:34,520 --> 02:47:40,439 thành viên và sau đó ở đây bạn thực sự có thể nói rằng chúng ta có một trường hợp của trường hợp Cha member and then in here you can actually say that we have a case of Father case 2077 02:47:40,439 --> 02:47:46,740 trường hợp mẹ anh trai và chúng tôi có một trường hợp chị ơi nhưng nếu chị muốn những trường hợp này thì sao mother case brother and we have a case sister but what if you want these cases 2078 02:47:46,740 --> 02:47:52,500 ví dụ như cha được gọi Bố ơi để có được giá trị đó thì con to for father for instance to be called Dad so to have that value of that so you 2079 02:47:52,500 --> 02:47:56,520 ví dụ như muốn có mẹ ngang bằng với mẹ thì con có thể nói Được want to for instance have a mother be equal to Mom then you can say Okay 2080 02:47:56,520 --> 02:48:00,300 bố là vậy đó mẹ là mẹ father is that mother is Mom 2081 02:48:00,300 --> 02:48:05,939 anh trai là anh trai và em gái là em gái được không nhưng bây giờ chúng ta sẽ gặp lỗi một cách đơn giản brother is bro and sister is sis okay but we're gonna get an error now simply 2082 02:48:05,939 --> 02:48:10,020 bởi vì nó nói rằng sự tích hợp này không thể có các giá trị như giá trị thô như because it says that this integration can't have values like raw values like 2083 02:48:10,020 --> 02:48:14,280 đây là điều bạn cần làm là nói như vậy nếu bảng liệt kê này có giá trị thô this what you need to do is to tell so if that this enumeration has raw values 2084 02:48:14,280 --> 02:48:19,380 của một kiểu dữ liệu cụ thể như thế này để bạn có thể nói về cơ bản nó là một chuỗi of a specific data type like this so you could say it is a string basically all 2085 02:48:19,380 --> 02:48:23,160 đúng và bây giờ Swift đang rất hạnh phúc nên những gì bạn có thể làm sau đó là nói gia đình right and now Swift is very happy so what you could do then is to say family 2086 02:48:23,160 --> 02:48:27,960 thành viên chấm cha và sau đó bạn có một tài sản mới ở đây gọi là giá trị thô member dot father and then you have a new property in here called raw value 2087 02:48:27,960 --> 02:48:34,080 sau đó bạn có thể lấy giá trị của bố đó ra khỏi Trường hợp của cha và nó là một chuỗi bạn có thể then you can grab that Dad value out of Father case and it is a string you could 2088 02:48:34,080 --> 02:48:38,880 làm điều tương tự với anh trai hoặc mẹ và em gái cũng được, anh trai cũng vậy do the same thing with brother or mother and sister as well okay so brother is 2089 02:48:38,880 --> 02:48:42,540 đang định nói anh bạn ở đây được rồi going to say bro in here okay 2090 02:48:42,540 --> 02:48:50,100 ừm bây giờ bạn cũng có thể có một bảng liệt kê trong Swift mà bạn có thể trích xuất um now you can also have a enumerations in Swift that have that you can extract 2091 02:48:50,100 --> 02:48:54,120 các trường hợp khác bởi vì nếu bạn đi vào thành viên gia đình lúc này other cases because if you go into family member at the moment 2092 02:48:54,120 --> 02:48:59,100 bạn có thể thấy rằng bạn có anh trai blah blah trong đó có giá trị thô nhưng bạn không có you can see that you have brother blah blah in it raw value but you don't have 2093 02:48:59,100 --> 02:49:04,680 bạn, bạn không có khả năng trích xuất tất cả các trường hợp bên trong này you you don't have the possibility of extracting all the cases inside this 2094 02:49:04,680 --> 02:49:09,479 lặp lại nhưng bạn có thể làm điều đó trong Swift bằng cách tuân thủ một giao thức gọi là trường hợp iteration but you can do that in Swift by conforming to a protocol called case 2095 02:49:09,479 --> 02:49:13,020 Tôi tăng tốc chúng ta chưa nói đến các giao thức nhưng chúng tôi sẽ làm điều đó I turbo we haven't talked about protocols yet we're going to do that 2096 02:49:13,020 --> 02:49:18,000 sẽ sớm thôi nhưng bây giờ chỉ cần thế là đủ nếu bạn hiểu cú pháp vì vậy hãy nói soon but for now just it's enough if you understand the syntax so let's say 2097 02:49:18,000 --> 02:49:23,340 đủ biểu tượng cảm xúc yêu thích và chúng tôi nói đó là một chuỗi và chúng tôi cũng vậy enough favorite emoji and we say it is a string and also we're 2098 02:49:23,340 --> 02:49:27,240 tuân theo một giao thức gọi là trường hợp I rắc rối được rồi, tạm thời hãy học nó đi conforming to a protocol called case I trouble okay just learn it for now that 2099 02:49:27,240 --> 02:49:31,740 nếu bạn làm điều này Swift cho phép bạn đi thông qua tất cả các trường hợp enum bằng cách sử dụng if you do this Swift allows you to go through all the enum cases using a 2100 02:49:31,740 --> 02:49:36,780 tài sản như bạn sẽ sớm thấy vì vậy hãy nói trường hợp má hồng bằng má hồng ở đây property as you'll soon see so let's say case blush is equal to blush in here 2101 02:49:36,780 --> 02:49:42,479 được rồi và chúng tôi nói tên lửa trường hợp là tên lửa trong okay and we say case rocket is rockets in 2102 02:49:42,479 --> 02:49:46,319 đây sau đó chúng tôi nói trường hợp cháy là here we then say case fire is 2103 02:49:46,319 --> 02:49:53,280 cứ bắn như thế này được rồi bạn có thể đi phía trước và nói biểu tượng cảm xúc yêu thích fire like this all right then you can go ahead and say favorites emoji 2104 02:49:53,280 --> 02:49:57,479 và như thế và chúng tôi nói rằng chúng tôi có một cái mới tài sản ở đây đột nhiên gọi tất cả and like that and we say we have a new property here all of a sudden call all 2105 02:49:57,479 --> 02:50:01,620 các trường hợp được rồi bạn có thể thấy nó nói tên lửa đỏ mặt và bắn để nó mang lại cho bạn cases all right you can see it says blush rocket and fire so it gives you 2106 02:50:01,620 --> 02:50:05,819 tất cả những trường hợp đó đều được và bạn cũng có thể lấy giá trị của họ bạn có thể nói yêu thích all those cases okay and also you can grab their values you can say favorite 2107 02:50:05,819 --> 02:50:10,380 biểu tượng cảm xúc không phải tất cả các trường hợp bây giờ chúng ta sẽ sử dụng một chức năng gọi là bản đồ và chúng tôi emoji not all cases now we're going to use a function called map and we're 2108 02:50:10,380 --> 02:50:13,620 sẽ nhận được giá trị thô của họ và làm ơn đừng lo lắng nếu điều này không có ý nghĩa going to get their raw value and please don't worry if this doesn't make sense 2109 02:50:13,620 --> 02:50:17,700 Tôi chỉ đang chứng minh những gì bạn có thể làm nhưng chúng ta sẽ nói về những điều này I'm just demonstrating what you can do but we're gonna talk about these things 2110 02:50:17,700 --> 02:50:23,040 sau này khi chúng ta nói về các bộ sưu tập trường hợp bây giờ là một mảng yêu thích của bạn when we talk about collections later all cases is now an array of your favorite 2111 02:50:23,040 --> 02:50:27,780 biểu tượng cảm xúc được rồi vì vậy nếu bạn tạo một liệt kê phù hợp với trường hợp này tôi emojis okay so if you make an enumeration conform to this case I 2112 02:50:27,780 --> 02:50:33,540 giao thức ba, tôi nghĩ nó thực sự là một giao thức vâng, vậy bạn có thể lấy triple protocol I think it is actually a protocol yes then you can you can grab 2113 02:50:33,540 --> 02:50:38,939 tất cả các trường hợp của bạn, uh, của bạn liệt kê sử dụng thuộc tính tất cả các trường hợp all the cases out of your uh out of your enumeration using all cases property 2114 02:50:38,939 --> 02:50:44,220 được rồi bây giờ bạn đã có bảng liệt kê, bạn có thể okay now now you have enumerations you can 2115 02:50:44,220 --> 02:50:49,319 Ý tôi là bạn có thể tạo các phiên bản của họ sử dụng như uh biểu tượng cảm xúc yêu thích.blosh also I mean you can create instances of them using like uh favorite emoji.blosh 2116 02:50:49,319 --> 02:50:55,920 biểu tượng cảm xúc yêu thích.rocket nhưng nếu bạn có nếu bạn có giá trị của một bảng liệt kê favorite emoji.rocket but if you have an if you have the value of an enumeration 2117 02:50:55,920 --> 02:51:00,960 làm thế nào bạn có thể tạo một phiên bản của nó như vậy bằng cách sử dụng như vậy ngay bây giờ chúng tôi đã có thể how can you create an instance of it so using so right now we have been able to 2118 02:51:00,960 --> 02:51:05,880 nói giá trị thô chấm biểu tượng cảm xúc yêu thích.blosh vì vậy chúng tôi nhận được giá trị nhưng nếu bạn có say favorite emoji.blosh dot raw value so we get the value but if you have the 2119 02:51:05,880 --> 02:51:12,060 giá trị bạn có thể đảo ngược nó thành màu đỏ mặt được không nếu bạn có một biểu tượng cảm xúc như thế này value can you reverse it into blush so if you have an emoji like this 2120 02:51:12,060 --> 02:51:16,800 bạn thực sự có thể lấy một ví dụ biểu tượng cảm xúc yêu thích bằng chính Biểu tượng cảm xúc can you actually grab an instance a favorite emoji using the Emoji itself 2121 02:51:16,800 --> 02:51:22,260 và vâng tất nhiên bạn có thể làm điều đó và Cú pháp của nó là nếu let đỏ mặt là and yes of course you can do that and the Syntax for it is if let blush is 2122 02:51:22,260 --> 02:51:28,859 biểu tượng cảm xúc yêu thích và bạn có thể nói bằng cách sử dụng giá trị thô của biểu tượng cảm xúc của bạn ở đây thì bạn favorite emoji and you can say using a raw value of your emoji in here then you 2123 02:51:28,859 --> 02:51:32,880 nói rằng đã tìm thấy biểu tượng cảm xúc đỏ mặt và sau đó bạn có thể in nó ra bàn điều khiển say found the blush emoji and then you can print it out to the console 2124 02:51:32,880 --> 02:51:40,500 nếu không thì Biểu tượng cảm xúc này không tồn tại như cái này khác nếu tôi có thể đánh vần nó ngay bây giờ otherwise this Emoji doesn't exist like this else if I can spell it right now 2125 02:51:40,500 --> 02:51:45,180 bạn có thể thấy nó nói đã tìm thấy má hồng biểu tượng cảm xúc và sau đó nó thực sự in nó ra you can see it says found the blush emoji and then it actually prints it out 2126 02:51:45,180 --> 02:51:50,220 thật là đỏ mặt, bản thân nó không phải là Biểu tượng cảm xúc bạn thấy đó thực sự là trường hợp đỏ mặt của which is blush it's not the Emoji itself you see it is actually the blush case of 2127 02:51:50,220 --> 02:51:53,700 biểu tượng cảm xúc bảng liệt kê biểu tượng cảm xúc yêu thích yêu thích the Emoji the favorite emojis enumeration favorite 2128 02:51:53,700 --> 02:51:57,720 biểu tượng cảm xúc bạn có thể thấy ở đây được chứ nhưng đừng lo lắng quá nhiều về điều này emoji you can see in here okay but don't worry too much about this 2129 02:51:57,720 --> 02:52:01,740 bởi vì chúng ta sẽ nói nhiều hơn về những điều này trong các chương sau khi chúng ta nói chuyện because we're going to talk more about these in later chapters when we talk 2130 02:52:01,740 --> 02:52:06,000 về các tùy chọn tại thời điểm này chúng tôi chưa có đã nói về các tùy chọn nên điều này có thể about optionals at the moment we haven't talked about optionals so this might 2131 02:52:06,000 --> 02:52:10,140 nhìn có vẻ hơi lạ khi đang suy nghĩ giếng phẳng là gì nó lạ quá look a little bit strange to be thinking what is a flat well it is strange 2132 02:52:10,140 --> 02:52:14,520 bởi vì chúng ta chưa nói về họ nhưng đây chỉ là một ví dụ được thôi because we haven't talked about them yet but this is just an example all right 2133 02:52:14,520 --> 02:52:19,279 hãy sao chép cái này và làm cái khác ví dụ sau đó chúng tôi nói hãy xem và tạo let's copy this as well and do another example then we say let's see and create 2134 02:52:19,279 --> 02:52:23,840 thay vì đỏ mặt ở đây chúng ta sẽ nói tuyết và chúng tôi nói instead of blush in here we're going to say snow and we say 2135 02:52:23,840 --> 02:52:29,819 tuyết thực sự tồn tại nên hãy đưa tuyết vào nhé ở đây và xem điều gì sẽ xảy ra bởi vì chúng ta snow exists really so let's Pass snow in here and see what happens because we 2136 02:52:29,819 --> 02:52:33,540 chưa xác định tuyết là một trong những trường hợp ở đây bạn thấy chúng ta không có tuyết haven't defined snow as one of the cases in here you see we don't have a snow 2137 02:52:33,540 --> 02:52:39,120 Biểu tượng cảm xúc như vậy và sau đó chúng tôi nói cố gắng tạo một ví dụ yêu thích Emoji so and then we say try to create an instance a favorite 2138 02:52:39,120 --> 02:52:44,399 biểu tượng cảm xúc với ghi chú này và nếu có tạo rồi gõ tuyết này tồn tại emoji with this note and if it is created then type this snow exists 2139 02:52:44,399 --> 02:52:52,200 thực sự ổn và sau đó chúng ta có thể ở đây nói như mong đợi tuyết không tồn tại trong em của chúng tôi really okay and then we can in here say as expected snow doesn't exist in our em 2140 02:52:52,200 --> 02:52:56,640 nên chúng tôi thực sự mong đợi được vào đây bởi vì tuyết không tồn tại như một trong những thứ so we expect actually to get in here because snow doesn't exist as one of the 2141 02:52:56,640 --> 02:53:02,460 trường hợp liệt kê của chúng tôi được rồi bây giờ chúng tôi đã xem xét những điều này và không cases of our enumeration okay now we've looked at these and don't 2142 02:53:02,460 --> 02:53:05,760 lo lắng về hai điều đặc biệt này ví dụ vì họ đang sử dụng tùy chọn worry about these two particular examples because they're using optionals 2143 02:53:05,760 --> 02:53:11,220 và chúng ta sẽ nói nhiều hơn về các lựa chọn trong phần tương lai được rồi bây giờ hãy nói về and we'll talk about options more in the future okay now let's talk about 2144 02:53:11,220 --> 02:53:17,819 bây giờ các thành viên của bảng liệt kê đang bị đột biến giống như trong các cấu trúc bạn có thể có mutating members of enumerations now just like in structures you can have 2145 02:53:17,819 --> 02:53:22,979 chức năng đột biến bên trong bảng liệt kê và cách để làm điều đó là thêm tiền tố mutating functions inside enumerations and the way to do that is by prefixing 2146 02:53:22,979 --> 02:53:28,200 chức năng đột biến như bạn đã làm với các cấu trúc, vì vậy hãy nói chiều cao enum the function with mutating as you did with structures so let's say enum height 2147 02:53:28,200 --> 02:53:33,359 và sau đó chúng tôi nói rằng chúng tôi có trường hợp bán khống trung bình và dài hạn và sau đó chúng ta có một and then we say we have cases of short medium and long and then we have a 2148 02:53:33,359 --> 02:53:40,200 đột biến funk ở đây Funk làm lâu rồi được rồi và bằng cách đột biến mutating funk in here Funk make long all right and by mutating 2149 02:53:40,200 --> 02:53:44,040 một bảng liệt kê bạn gần như chỉ gán một giá trị mới cho bản thân vì an enumeration you're pretty much just assigning a new value to self because 2150 02:53:44,040 --> 02:53:46,920 không còn nhiều nữa bạn có thể tắt tiếng nó với một bảng liệt kê hơn thực tế there's not much more you can mute it with an enumeration than actually 2151 02:53:46,920 --> 02:53:53,640 nó tự biến đổi nên ở đây bạn có thể nói bản thân bằng chiều cao chấm dài mutating it itself so in here then you can say self is equal to height dot long 2152 02:53:53,640 --> 02:53:59,640 được rồi, về cơ bản bạn có thể chỉ định nó trở lại với chính mình và thay đổi all right so you can basically assign it back to your own self and change 2153 02:53:59,640 --> 02:54:05,520 ví dụ về chính bạn bằng cách sử dụng một đột biến chức năng trên một bảng liệt kê được rồi, vậy hãy yourself instance using a mutating function on an enumeration okay so let's 2154 02:54:05,520 --> 02:54:10,500 hãy tiếp tục và nói rằng chúng ta có một biến chiều cao bằng chiều cao trung bình và go ahead and say we have a variable my height is equal to height medium and 2155 02:54:10,500 --> 02:54:15,720 sau đó chúng tôi nói chiều cao của tôi sẽ dài ra và sau đó chúng ta nói chiều cao của tôi hãy xem nó là gì then we say my height make long and then we say my height let's see what it is 2156 02:54:15,720 --> 02:54:20,760 vì vậy một khi nó được thực hiện đầu tiên là trung bình và sau đó chúng tôi tạo ra độ cao bằng so once it is executed first is medium and then we made the heights equal to 2157 02:54:20,760 --> 02:54:27,359 ở đây lâu như bạn có thể thấy được và nếu đây là hằng số let thì bạn long in here as you can see okay and if this was a let constant then you 2158 02:54:27,359 --> 02:54:32,460 sẽ không thể làm điều này bạn sẽ thấy bây giờ lệnh make long không thể thực thi được wouldn't be able to do this you will see now that make long can't be executed 2159 02:54:32,460 --> 02:54:37,260 đơn giản vì nó đang cố gắng biến đổi bản thân ổn thôi simply because it is trying to mutate self all right 2160 02:54:37,260 --> 02:54:42,660 tốt bây giờ chúng ta đã hoàn thành việc đó và có một Khái niệm khác trong Swift good now we're done with that now and there is another Concept in Swift 2161 02:54:42,660 --> 02:54:46,260 lặp đi lặp lại nhiều hơn một chút nâng cao nhưng tôi chỉ muốn đặt tên cho nó iterations which is a little bit more advanced but I wanted to just name it 2162 02:54:46,260 --> 02:54:50,939 và chúng được gọi là đệ quy liệt kê hoặc lặp lại gián tiếp và and they're called recursive enumerations or indirect iterations and 2163 02:54:50,939 --> 02:54:56,000 trong tất cả những năm làm việc ở Swift, tôi nghĩ rằng tôi đã sử dụng chúng một hoặc hai lần in all my years of working in Swift I think I've used them once once or twice 2164 02:54:56,000 --> 02:55:00,540 rất hiếm khi bạn thấy liệt kê gián tiếp và đó là lý do tại sao it is very uncommon that you see indirect enumerations and that's why 2165 02:55:00,540 --> 02:55:04,200 Tôi đã để lại chúng như ý tưởng cuối cùng để giải thích nó ở đây nhưng tôi nghĩ nó vẫn là một I've left them as the last concept to explain it here but I think it's still a 2166 02:55:04,200 --> 02:55:09,180 ý kiến ​​hay đấy, ừ, giải thích chúng đi, vậy hãy để tôi cho bạn thấy những gì gián tiếp hoặc đệ quy good idea uh to explain them so let me show you what indirect or recursive 2167 02:55:09,180 --> 02:55:14,460 liệt kê ngắn gọn là đệ quy Đổi mới như tên gọi của nó chỉ ra là một enumerations are in short a recursive Innovation as its name indicates is an 2168 02:55:14,460 --> 02:55:18,359 bảng liệt kê đề cập đến chính nó như vậy trong ở đây bạn có thể thấy chúng tôi đã có Tích hợp enumeration that refers to itself so in here you can see we had Integrations 2169 02:55:18,359 --> 02:55:22,439 chỉ có ngắn vừa dài và thậm chí chúng tôi đã lặp lại ở đây với that just have short medium long and even have we had iterations in here with 2170 02:55:22,439 --> 02:55:26,040 Các giá trị liên quan mà chúng tôi không có đề cập đến chính họ bạn có thể thấy trong Associated values that we're not referring to themselves you can see in 2171 02:55:26,040 --> 02:55:30,779 ở đây họ chỉ có các giá trị liên kết của URL nhưng không có giá trị liên quan của cảm ứng here they just had associate values of URL but no Associated values of touch 2172 02:55:30,779 --> 02:55:34,620 phím tắt một lần nữa được rồi nhưng hãy tiếp tục và tạo một bảng liệt kê mới ở đây shortcut again okay but let's go ahead and create a new enumeration in here 2173 02:55:34,620 --> 02:55:39,720 có liên quan đến chính nó, chúng tôi nói hoạt động int enum which has reference to itself we say enum int operation 2174 02:55:39,720 --> 02:55:45,300 và sau đó chúng ta nói rằng chúng ta có một phép cộng hãy nói như vậy chúng ta là người cũ về cơ bản chúng ta là nhau and then we say we have a an addition let's say so we're ex we're basically 2175 02:55:45,300 --> 02:55:50,760 định nghĩa phép cộng giữa hai số nguyên được rồi nên đó chỉ là một trường hợp thôi defining an addition between two integers okay so it's just a case it's 2176 02:55:50,760 --> 02:55:55,380 không phải là một hàm chúng ta nói k trừ và sau đó chúng ta trừ trừ giữa not a function we say k subtract and then we subtraction subtractions between 2177 02:55:55,380 --> 02:56:00,960 hai số nguyên và sau đó chúng ta có thể rảnh tay đây là một điều đặc biệt à two integers as well and then we can have a free hand this is a special uh 2178 02:56:00,960 --> 02:56:05,939 trường hợp mà chúng tôi đang tạo đề cập đến bản thân hoạt động của ins cũng ổn vậy thì sao case that we're creating which refers to ins operation itself all right so what's 2179 02:56:05,939 --> 02:56:09,660 đang xảy ra ở đây bây giờ bạn thấy chúng tôi sẽ lại xảy ra lỗi nói rằng bạn không thể happening in here now you see we'll again an error saying that you cannot 2180 02:56:09,660 --> 02:56:15,660 có lỗi bạn không thể tham khảo được trừ khi bạn đánh dấu bảng liệt kê này là have error you cannot refer to yourself unless you mark this enumeration as an 2181 02:56:15,660 --> 02:56:21,840 enum gián tiếp như bạn có thể thấy ở đây được rồi, bây giờ bạn có thể thấy vấn đề đó đã xảy ra indirect enum as you can see in here okay so you can now see that issue has 2182 02:56:21,840 --> 02:56:26,640 đã biến mất nhưng thực ra cái này có tác dụng gì thực sự có ý nghĩa và ý nghĩa của nó là disappeared but what does this actually really mean and what it means is that 2183 02:56:26,640 --> 02:56:32,040 bây giờ bạn có thể tự do thao tác bằng tay về hoạt động này và tôi hoàn toàn now you can have a free hand operation on this ins operation and I I completely 2184 02:56:32,040 --> 02:56:35,279 hiểu điều này là một chút phức tạp và chúng ta không cần phải học understand this is a little bit complicated and we don't have to learn 2185 02:56:35,279 --> 02:56:39,300 cái này nhưng chúng ta hãy xem làm thế nào bây giờ chúng ta có thể tạo một hàm trên cái này this but let's just let's just see how we can create a function now on this 2186 02:56:39,300 --> 02:56:44,279 phép liệt kê tính toán kết quả dựa trên các trường hợp giả sử chúng ta có enumeration that calculates the results based on the cases let's say we have 2187 02:56:44,279 --> 02:56:50,840 trò đùa tính toán kết quả và chúng tôi nói rằng funk calculates results and we say that the 2188 02:56:50,840 --> 02:56:57,120 tham số tắt hoạt động và chúng tôi nói hoạt động ở đây được rồi parameter is off operation and we say ins operation in here okay as 2189 02:56:57,120 --> 02:57:00,600 không bắt buộc và chúng tôi nói rằng nó bằng con số không optional and we say that's equal to nil 2190 02:57:00,600 --> 02:57:04,080 và một lần nữa tôi hoàn toàn hiểu chúng ta cũng chưa nói về những điều này and again I completely understand we haven't talked about these yet either 2191 02:57:04,080 --> 02:57:09,899 và ở đây về cơ bản chúng ta có thể tính toán các hoạt động và bằng cách thực hiện một and in here we could then basically calculate the operations and by doing a 2192 02:57:09,899 --> 02:57:12,779 câu lệnh chuyển đổi Tôi chỉ là tôi vừa đi dán nó vào đây để chúng ta không có switch statement I'm just I'm just going to paste that in here so we don't have 2193 02:57:12,779 --> 02:57:15,359 để gõ tất cả những điều này một cách trung thực với Cậu không sao chứ to type all of this to be honest with you okay 2194 02:57:15,359 --> 02:57:20,160 vậy hãy xem điều gì đang xảy ra ở đây hoạt động hoặc tự so let's see what happening here we have the operation or self 2195 02:57:20,160 --> 02:57:24,479 một giá trị trả về không có giá trị bất ngờ và ở đây chúng ta nên trả về một số nguyên là an unexpected non-void return value and in here we should return an integer as 2196 02:57:24,479 --> 02:57:28,680 ừ được rồi vậy chuyện gì đang xảy ra vậy về cơ bản chúng tôi đang bật tính năng này well okay so what's happening is that we're we're basically switching on this 2197 02:57:28,680 --> 02:57:31,800 hoạt động vì nó là tùy chọn, chúng tôi nói hoạt động hoặc tự operation since it's optional we're saying either the operation or self 2198 02:57:31,800 --> 02:57:36,359 chính nó và chúng tôi đang nói nếu nó là một phép cộng thì thực hiện phép cộng nếu đó là một itself and we're saying if it's an addition then do addition if it's a 2199 02:57:36,359 --> 02:57:40,020 phép trừ thực hiện phép trừ nếu nó miễn phí hãy thực sự thay đổi điều này thành subtraction do subtraction if it's free hand let's actually change this to 2200 02:57:40,020 --> 02:57:45,660 tự do viết hoa chữ H nếu tôi có thể đánh vần nếu nó tự do thì hãy gọi hàm này freehand with a capital H if I can spell if it's freehand then call this function 2201 02:57:45,660 --> 02:57:51,000 đệ quy với thao tác đó và kết quả của việc này thực sự là recursively with that operation and the result to this really is that 2202 02:57:51,000 --> 02:57:54,779 bây giờ bạn có thể tiếp tục và nói hãy để tự do you can go ahead now and say let freehand 2203 02:57:54,779 --> 02:58:02,279 đang đi vào hoạt động dot tự do được rồi và ở đây bạn có thể nói làm phép cộng is into operation dot freehand okay and in here then you can say do an addition 2204 02:58:02,279 --> 02:58:07,920 của hai và bốn và sau đó bạn có thể tự do nói uh và bạn of two and four and then you can say freehand uh and you 2205 02:58:07,920 --> 02:58:13,380 có thể nói kết quả tính toán chấm tự do và sau đó bạn có thể thấy kết quả là can say freehand dot calculate results and then you can see the result being 2206 02:58:13,380 --> 02:58:17,880 được in ở đây gồm sáu một lần nữa xin đừng lo lắng điều này rất printed in here of six again please don't worry this is very 2207 02:58:17,880 --> 02:58:22,260 phức tạp điều này gần như sẽ thích Swift nâng cao và như tôi đã nói trong tất cả complicated this is almost going to like Advanced Swift and as I said in all my 2208 02:58:22,260 --> 02:58:26,880 năm làm việc với ừm Swift tôi đã phải sử dụng, tôi nghĩ một lần hoặc years of working with um Swift I've had to use I think once or 2209 02:58:26,880 --> 02:58:31,620 hai lần lặp lại gián tiếp và nếu bạn không học được điều này, nó hoàn toàn ổn twice uh indirect iterations and if you didn't learn this it's completely fine 2210 02:58:31,620 --> 02:58:35,399 người ta mong đợi sẽ trả lời nó và đó là một trong những lý do khiến tôi thuộc loại it was kind of expected to answer it and that's one of the reasons I'm kind of 2211 02:58:35,399 --> 02:58:39,779 nhảy qua nó và dán mã bởi vì Tôi không nghĩ có nhiều giá trị trong đó jumping over it and pasting code because I don't think there's so much value in 2212 02:58:39,779 --> 02:58:45,960 dành thời gian tìm hiểu về gián tiếp hoặc liệt kê đệ quy vì vậy chỉ cần biết rằng spending time learning about indirect or recursive enumerations so just know that 2213 02:58:45,960 --> 02:58:51,300 chúng tồn tại nhưng bạn không cần phải học được thôi vậy hãy đóng cửa lại they exist but you don't have to learn it okay so let's close off the 2214 02:58:51,300 --> 02:58:56,640 chương lặp lại với gián tiếp này lặp lại và đó có lẽ là tốt hơn iterations chapter with this indirect iteration and that is probably a better 2215 02:58:56,640 --> 02:58:59,760 ý tưởng thực sự là nếu bạn loại bỏ cái này toàn bộ mọi thứ từ đây vì vậy bạn không có idea actually if you just remove this whole thing from here so you don't have 2216 02:58:59,760 --> 02:59:04,040 bị chế nhạo bởi ý nghĩ có lặp lại gián tiếp to be taunted by the thought of having indirect iterations 2217 02:59:04,040 --> 02:59:08,760 vậy thì ít nhất đối với tôi nó không có cảm giác như vậy thật tốt khi kết thúc chương bằng điều gì đó so uh at least for me it doesn't feel so good to end the chapter with something 2218 02:59:08,760 --> 02:59:13,439 rằng chúng tôi vừa nhảy qua nhưng tôi chỉ muốn để giải thích rằng điều này tồn tại để bạn biết that we just jumped over but I just want to explain that this exists so you know 2219 02:59:13,439 --> 02:59:18,180 về chuyện đó được rồi tốt bây giờ chúng ta đã hoàn thành việc liệt kê trong about it okay good now we're done with enumerations in 2220 02:59:18,180 --> 02:59:22,500 phần tiếp theo của video này chúng ta chúng ta sẽ nói về các lớp học bây giờ the next section of this video we're gonna talk about classes now that we've 2221 02:59:22,500 --> 02:59:27,060 đã nói đủ về bảng liệt kê rồi hãy tiếp tục và nói về khái niệm tiếp theo talked enough about enumerations let's go ahead and talk about the next concept 2222 02:59:27,060 --> 02:59:31,140 mà chúng tôi thực sự đã đặt tên trước đó và bạn có thể biết họ từ nơi khác which we've actually named before and you probably know them from other 2223 02:59:31,140 --> 02:59:35,700 ngôn ngữ lập trình mà bạn đang đã quen thuộc với khái niệm đó programming languages that you're already familiar with and that concept 2224 02:59:35,700 --> 02:59:40,380 là các lớp vì vậy hãy tạo một lớp riêng ừm is classes so let's create a separate um 2225 02:59:40,380 --> 02:59:45,899 sân chơi trống cho việc này vì vậy hãy nói sân chơi ở đây và chúng tôi nói trống blank playground for this so let's say playground in here and we say blank 2226 02:59:45,899 --> 02:59:50,100 sân chơi và hãy gọi nó là các lớp học và một lần nữa hãy đảm bảo rằng bạn đang tạo playground and let's call it classes and just again ensure that you're creating 2227 02:59:50,100 --> 02:59:57,359 nó bên trong thư mục chính hoặc không gian làm việc của bạn và sau đó chúng tôi nói ở đây tạo ra it inside your main folder or workspace and then we say in here create 2228 02:59:57,359 --> 03:00:02,160 và như chúng tôi thường làm, chúng tôi chỉ nói rằng chúng tôi cần nhập kem nền vào cái này and like we usually do we just say we need to import foundation in this 2229 03:00:02,160 --> 03:00:07,439 sân chơi và một lần nữa giữ và trackpad vào đây và tự động nói playground and again hold and the trackpad in here and say automatically 2230 03:00:07,439 --> 03:00:12,660 chạy ổn vì vậy chúng tôi có cấu trúc trong Swift và chúng tôi run okay so we have structures in Swift and we 2231 03:00:12,660 --> 03:00:18,180 cũng có bảng liệt kê nhưng có một loại không gian lưu trữ thứ ba bạn also have enumerations but there's a third category of storage space you 2232 03:00:18,180 --> 03:00:24,180 có thể nói trong trí nhớ và đó được gọi là lớp và các lớp giống như could say in memory and that is called a class and and classes are like 2233 03:00:24,180 --> 03:00:30,000 cấu trúc nhưng chúng không phải là loại giá trị chúng là loại tham chiếu và chúng cũng structures but they're not value types they're reference types and also they 2234 03:00:30,000 --> 03:00:34,979 cho phép khả năng thay đổi mà không cần phải tiền tố ví dụ như đột biến allow for mutability without having to prefix things for instance with mutating 2235 03:00:34,979 --> 03:00:40,500 một cú pháp hoặc từ khóa vì vậy hãy cùng xem tại một lớp học đơn giản ở đây nên tôi chỉ a syntax or keyword so let's have a look at a simple class in here so I'm just 2236 03:00:40,500 --> 03:00:46,200 sẽ nói người đẳng cấp và hãy nói Tên VAR Chuỗi và sau đó thanh tuổi kết thúc going to say class person and let's say VAR name String and then bar age ends 2237 03:00:46,200 --> 03:00:49,920 được rồi và vì vậy đây là một lớp đơn giản bây giờ nó có okay and so this is a simple class now it has 2238 03:00:49,920 --> 03:00:53,340 hai biến và hãy xem ồ chúng ta gặp lỗi ở đây và đơn giản là two variables and let's see oh we're getting an error in here and simply 2239 03:00:53,340 --> 03:00:56,880 bởi vì chúng tôi không có bộ khởi tạo và cái này thực sự là chúng tôi đang có được điều rất tốt because we have no initializers and this is actually really good we're getting 2240 03:00:56,880 --> 03:00:59,220 lỗi này ừm vì this error um because 2241 03:00:59,220 --> 03:01:03,300 ừm tôi thực sự không nghĩ đến việc giải thích cái này đầu tiên nhưng bây giờ nó đã xuất hiện um I actually didn't think of explaining this first but now that it has appeared 2242 03:01:03,300 --> 03:01:08,580 hãy nói về nó như bạn đã thấy trước đây nếu bạn có một cấu trúc như hãy nói trong let's talk about it as you saw before if you have a structure like let's say in 2243 03:01:08,580 --> 03:01:11,760 ở đây chúng tôi nói xin lỗi lớp người nhé struct người here we say class person sorry struct person 2244 03:01:11,760 --> 03:01:15,600 và hãy thực sự đặt chính xác như vậy mã bên trong cấu trúc và nhận xét and let's actually put exactly the same code inside the structure and comment 2245 03:01:15,600 --> 03:01:20,340 lớp học ra ngoài và bạn có thể thấy mọi thứ sẽ ổn với cấu trúc mà bạn the class out and you can see everything will just go fine with the structure you 2246 03:01:20,340 --> 03:01:24,800 không cần một bộ khởi tạo hoặc một Trình xây dựng cho một cấu trúc theo mặc định don't need an initializer or a Constructor for a structure by default 2247 03:01:24,800 --> 03:01:30,300 một cái ngầm sẽ được tạo cho bạn với tất cả các biến thành viên được thêm vào an implicit one will be created for you with all the member variables added to 2248 03:01:30,300 --> 03:01:35,399 danh sách đối số của Trình xây dựng vì vậy nếu bạn nói người bạn có thể thấy tên và the argument list of the Constructor so if you say person you can see name and 2249 03:01:35,399 --> 03:01:39,720 tuổi đã có rồi tuy nhiên khi nói đến lớp học bạn age are already there however when it comes to classes you 2250 03:01:39,720 --> 03:01:43,979 luôn phải tạo ra các Constructor bản thân bạn có một tính năng tái cấu trúc always have to create Constructors yourself there is a refactoring feature 2251 03:01:43,979 --> 03:01:48,300 trong xcode nơi bạn có thể yêu cầu xcode tạo Trình xây dựng cho bạn. Tôi không in xcode where you can ask xcode to create the Constructor for you I'm not 2252 03:01:48,300 --> 03:01:52,020 chắc chắn nếu nó có sẵn bên trong ừ sân chơi và chúng ta có thể thấy điều đó sure if it is available inside um playgrounds and we can see that it 2253 03:01:52,020 --> 03:01:58,080 không lẽ có một thực đơn ở đâu đó giả sử là Trình xây dựng hoặc isn't maybe there is a menu somewhere let's let's say Constructor or 2254 03:01:58,080 --> 03:02:02,939 trình khởi tạo tạo thành viên khôn ngoan bộ khởi tạo và đó là cái nhưng nó initializer generate member-wise initializer and that's the one but it 2255 03:02:02,939 --> 03:02:06,540 dường như không thực sự có tác dụng sân chơi nên chúng ta chỉ cần sử dụng cái này doesn't seem to really work in playgrounds so we need to just use this 2256 03:02:06,540 --> 03:02:09,720 gợi ý nhỏ ở đây và yêu cầu nó có lẽ little hint in here and ask it to perhaps 2257 03:02:09,720 --> 03:02:15,000 ôi vâng, nó không thực sự cho phép chúng tôi thực tế là thêm một trình khởi tạo mà nó đang cố gắng oops yes it is not really allowing us to actually add an initializer it's trying 2258 03:02:15,000 --> 03:02:18,240 để thêm một giá trị mặc định cho những giá trị này tài sản và đó không phải là những gì chúng tôi muốn to add a default value to these properties and that's not what we want 2259 03:02:18,240 --> 03:02:24,000 để làm như vậy sự khác biệt đầu tiên của một lớp học cấu trúc là nó cần phải có một to do so a class's first difference to a structure is that it needs to have a 2260 03:02:24,000 --> 03:02:29,100 Trình xây dựng hoặc trình khởi tạo và chúng tôi đã biết Cú pháp cho nó và cái đó Constructor or an initializer and we already know the Syntax for it and that 2261 03:02:29,100 --> 03:02:33,720 ở trong nó và sau đó ở trong dấu ngoặc đơn bạn sẽ thêm đối số của mình is within it and then in in the parenthesis you would add your arguments 2262 03:02:33,720 --> 03:02:37,680 ở đây được rồi, vậy hãy coi như chúng ta có một cái tên đó là một chuỗi và sau đó H là một in here okay so let's say we have a name which is a string and then H which is an 2263 03:02:37,680 --> 03:02:42,779 INT và một lần nữa ừm thực ra không phải nữa chúng ta chưa từng nói về điều này trước đây nhưng INT and again the um not again actually we haven't talked about this before but 2264 03:02:42,779 --> 03:02:46,680 thứ tự của những lập luận này không nhất thiết phải là the ordering of these arguments it doesn't necessarily have to be the 2265 03:02:46,680 --> 03:02:49,920 sắp xếp các tài sản của bạn để nó có thể được bất cứ điều gì ở đây và bạn thực sự có thể ordering of your properties so it can be anything in here and you can actually 2266 03:02:49,920 --> 03:02:54,840 yêu cầu nhiều thứ hơn hãy nói chiều cao và tôi không biết bạn muốn làm gì ask for more stuff let's just say height and I don't know what you want to do 2267 03:02:54,840 --> 03:02:58,260 với điều đó bởi vì bạn là chúng tôi không có đặt vào lúc này để lưu trữ nó nhưng bạn with that because you're we don't have a place at the moment to store it but you 2268 03:02:58,260 --> 03:03:03,260 có thể yêu cầu nhiều thứ hơn lớp của bạn thực sự có thuộc tính vì có lẽ can ask for more things than your class actually has as properties because maybe 2269 03:03:03,260 --> 03:03:07,560 một số giá trị đó sẽ là sử dụng các cách khác bên trong Trình xây dựng some of those values are going to be using other ways inside the Constructor 2270 03:03:07,560 --> 03:03:12,479 của lớp bạn được rồi vậy hãy lấy cái này quay lại có tên và đại lý ở đây tất cả of your class okay so let's take this back to having name and agent here all 2271 03:03:12,479 --> 03:03:17,939 bên phải và sau đó bên trong Trình xây dựng của bạn Công việc trước hết là đảm bảo rằng right and then inside a Constructor your job is to first and foremost ensure that 2272 03:03:17,939 --> 03:03:22,740 lớp của bạn là thuộc tính đã được thiết lập trước khi Trình xây dựng kết thúc your class as properties are all set before the Constructor is finished so 2273 03:03:22,740 --> 03:03:27,420 bạn không thể quay lại từ Trình xây dựng hoặc một trình khởi tạo như Swift gọi nó và you cannot return from a Constructor or an initializer as Swift calls it and 2274 03:03:27,420 --> 03:03:33,000 mà không cần khởi tạo hoặc tất cả thuộc tính được lưu trữ được nên nó báo tên without having initialized or all your stored properties okay so it says name 2275 03:03:33,000 --> 03:03:37,500 cần được lưu trữ tôi cần tên cần về cơ bản có một giá trị và sau đó chúng tôi needs to be stored I need name needs to basically have a value and then we're 2276 03:03:37,500 --> 03:03:40,859 sẽ tiếp tục và tự nói rằng đó là tên going to go ahead and say self that's name 2277 03:03:40,859 --> 03:03:46,920 tự cái tên đó bằng tên đúng và rồi chúng ta cũng phải nói self-h là self that name is equal to name right and then we also have to say self-h is 2278 03:03:46,920 --> 03:03:51,060 bằng H được rồi, đó là điều đơn giản equal to H alright so that's that's the simple 2279 03:03:51,060 --> 03:03:55,319 trình khởi tạo nhưng chúng tôi chưa thực sự xem xét về khả năng thay đổi, hãy có một chức năng trong initializer but we haven't really looked at mutability let's have a function in 2280 03:03:55,319 --> 03:04:00,840 ở đây và nói tăng H được rồi và thì ở đây chúng ta nói tuổi của bản thân là và here and say increase H all right and then in here we say self age is and 2281 03:04:00,840 --> 03:04:04,859 chúng tôi đang sử dụng toán tử này ở đây về cơ bản chiếm phía bên trái và we're using this operator in here which basically takes the left hand side and 2282 03:04:04,859 --> 03:04:11,279 thêm vế phải vào nhé vậy bây giờ chúng tôi có một chức năng ở đây bạn adds the right hand side to it all right so now we have a function in here you 2283 03:04:11,279 --> 03:04:16,080 có thể thấy nó đang tăng thuộc tính tuổi bởi một và nó không nhất thiết phải là tiền tố can see it's increasing the age property by one and it doesn't have to be prefix 2284 03:04:16,080 --> 03:04:20,880 thực sự với việc đột biến, tôi nghĩ nếu bạn gõ đột biến vào đây nó sẽ cho bạn một with mutating actually I think if you type mutating in here it will give you a 2285 03:04:20,880 --> 03:04:25,920 ví dụ lỗi cú pháp không hợp lệ các phương thức và lớp học vì vậy bạn không nên syntax error is not valid on instance methods and classes so you shouldn't 2286 03:04:25,920 --> 03:04:30,540 thực sự có tiền tố bất cứ điều gì trong của bạn các lớp có đột biến được rồi bạn actually prefix anything in your in your classes with mutating all right then you 2287 03:04:30,540 --> 03:04:35,819 có thể tiếp tục và tạo một phiên bản của lớp này hãy nói rằng Foo là một can go ahead and create an instance of this class let's say let's Foo is a 2288 03:04:35,819 --> 03:04:40,620 người có tên Foo và tuổi là 20. được rồi tôi sẽ nghỉ person with the name of Foo and the age of 20. all right then I'm going to break 2289 03:04:40,620 --> 03:04:45,540 những thứ này thành dòng riêng của họ thì chúng ta sẽ nói Foo H có một these into their own lines then we're going to say Foo H have a 2290 03:04:45,540 --> 03:04:49,680 nhìn vào tuổi và sau đó chúng ta nói Foo tăng tuổi rồi full H nhé look at the age and then we say Foo increase age and then full H all right 2291 03:04:49,680 --> 03:04:54,720 vì vậy chúng ta hãy xem xét những giá trị này thì bạn có thể thấy đầu tiên tuổi của Foo là so let's have a look at these values then you can see first the age of Foo is 2292 03:04:54,720 --> 03:04:59,460 20 và sau đó suy nghĩ sau khi tăng nó bằng cách sử dụng 20 and then after think after incrementing it using the 2293 03:04:59,460 --> 03:05:04,500 tăng tuổi thì ta được H bằng 20. vậy thực sự thì bạn không ở đâu ở đây cả increase age then we get the H equal to 20. so nowhere in here did you actually 2294 03:05:04,500 --> 03:05:09,120 phải tạo ra bất cứ thứ gì đột biến và bạn có thể thấy rằng chính biến đó là have to create anything mutating and you can see that the variable itself is 2295 03:05:09,120 --> 03:05:14,160 thực sự được tạo bằng let nên đó là sự khác biệt thứ hai khi bạn tạo một actually created with a let so that's the second difference when you create a 2296 03:05:14,160 --> 03:05:20,100 đặt hằng số bằng một thể hiện của a lớp bạn không thể gán giá trị mới cho let constant equal to an instance of a class you cannot assign a new value to 2297 03:05:20,100 --> 03:05:23,640 hằng số chọn không đổi vì có một trong những bản chất của bên trái the select constants constant because there is one of the natures of a left 2298 03:05:23,640 --> 03:05:27,600 không đổi sau khi tạo, nó không thể được gán một giá trị mới nên bạn không thể đi constant after creation it cannot be assigned a new value so you cannot go 2299 03:05:27,600 --> 03:05:30,840 phía trước và nói Foo bằng với một số khác người ở đây ahead and say Foo is equal to some other person in here 2300 03:05:30,840 --> 03:05:36,180 vì vậy quy tắc đó vẫn giữ nguyên khi nó đến để cho các hằng số và các lớp so that rule stays the same when it comes to let constants and classes 2301 03:05:36,180 --> 03:05:41,880 tuy nhiên kể từ bây giờ bạn đang làm việc với hằng số let bằng với một thể hiện của however since now you're working with the let constant equal to an instance of 2302 03:05:41,880 --> 03:05:46,920 một lớp lớp này nội bộ có thể thay đổi như bạn có thể thấy tuổi tác đã thay đổi a class this class internally can change as you can see the age has changed 2303 03:05:46,920 --> 03:05:51,240 mà không cần bạn phải thay đổi điều này thành xa vậy đó là sự khác biệt thứ hai without you having to change this to afar so that's the second difference 2304 03:05:51,240 --> 03:05:57,960 giữa các lớp và cấu trúc trong đó các lớp cho phép khả năng thay đổi nội bộ between classes and structures in that classes allow for internal mutability 2305 03:05:57,960 --> 03:06:03,479 mà không cần bạn phải tạo một tài khoản thực tế VAR trong số họ đều ổn và cả của họ nữa without you having to create an actual VAR out of them all right and also their 2306 03:06:03,479 --> 03:06:07,080 các loại tài liệu tham khảo và chúng ta sẽ nói về điều đó sẽ sớm thực sự ổn thôi reference types and we'll talk about that soon actually okay 2307 03:06:07,080 --> 03:06:12,060 vì vậy chúng ta hãy và hãy xem những gì các loại tham chiếu thực sự có nghĩa như vậy ở đây so let's and let's have a look at what reference types actually mean so in here 2308 03:06:12,060 --> 03:06:18,060 chúng ta nói Foo age hãy giải quyết chuyện này đi Foo H có lẽ chỉ cần gõ lại vào đây và we say Foo age let's bring this down Foo H maybe just type it again in here and 2309 03:06:18,060 --> 03:06:23,340 thì chúng ta nói thanh ngang bằng với thức ăn đúng rồi ta nói thanh tăng H bây giờ then we say bar is equal to food all right and then we say bar increase H now 2310 03:06:23,340 --> 03:06:28,500 bạn có thể mong đợi thanh được sao chép và thực sự có một bản sao mới của Foo you'd probably expect bar to be copied and have actually a new copy of Foo 2311 03:06:28,500 --> 03:06:32,460 tuy nhiên vì các lớp là tham chiếu gõ tham chiếu của Foo này là however since classes are reference types the reference of this Foo is 2312 03:06:32,460 --> 03:06:38,399 được đặt bên trong thanh này khá nhiều sau dòng 30. quầy bar và đồ ăn trỏ tới placed inside this bar so pretty much after line 30. bar and food point to the 2313 03:06:38,399 --> 03:06:43,800 như nhau ví dụ về người trong bộ nhớ để thanh được same instance of person in memory so bar gets 2314 03:06:43,800 --> 03:06:48,960 một tham chiếu đến Foo này và sau đó bởi tăng tuổi của thanh thì tuổi Foos a reference to this Foo and then by increasing the age of bar then Foos age 2315 03:06:48,960 --> 03:06:55,500 cũng được tăng lên và thanh H chính xác là giống nhau nên về cơ bản họ đang chỉ is also increased and bars H is exactly the same so they're basically pointing 2316 03:06:55,500 --> 03:07:01,200 vào cùng bộ nhớ và không gian bộ nhớ hoặc bộ nhớ được phân bổ bộ nhớ cho việc này to the same memory and memory space or memory allocated memory for this 2317 03:07:01,200 --> 03:07:05,960 ví dụ về người đó được rồi vì vậy hãy giữ trong tâm trí nó rất rất quan trọng person's person instance okay so keep that in mind it's very very important 2318 03:07:05,960 --> 03:07:13,319 bây giờ bạn cũng có thể so sánh các trường hợp của các lớp bằng cách sử dụng bằng nhau để now you can also compare instances of classes by using the equal equal so the 2319 03:07:13,319 --> 03:07:17,160 cú pháp gấp ba lần bằng nhau mà trong tất cả của tôi đã làm việc nhiều năm rồi nên nếu tôi chưa bao giờ triple equal syntax which in all my years are working with so if I've never 2320 03:07:17,160 --> 03:07:23,700 phải sử dụng nên rất khó xảy ra điều đó tuy nhiên bạn sẽ phải sử dụng nó nếu bạn had to use so it is very unlikely that you'll have to use it however if you 2321 03:07:23,700 --> 03:07:28,560 muốn xem liệu hai trường hợp của một biến trỏ đến một lớp được trỏ want to see if two instances of a variable pointing to a class are pointed 2322 03:07:28,560 --> 03:07:33,660 tại cùng một không gian bộ nhớ thì bạn sẽ sử dụng cú pháp này at the at the exact same memory space then you would use this syntax you would 2323 03:07:33,660 --> 03:07:38,040 nói nếu Rất tiếc nếu tôi có thể đánh vần thì bằng nhau say if Foo oops if I can spell is equal equal 2324 03:07:38,040 --> 03:07:41,939 quán ba được rồi và tôi nghĩ tôi thực sự đã đặt bar okay and I think I've placed actually my 2325 03:07:41,939 --> 03:07:45,420 ngón tay bên phải không đúng chỗ trên bàn phím nên đó là lý do tại sao tôi đang gõ fingers on the right on the wrong place on the keyboard so that's why I'm typing 2326 03:07:45,420 --> 03:07:48,960 mọi thứ đều không chính xác nên hãy nói Foo và thanh everything incorrectly so let's say Foo and Bar 2327 03:07:48,960 --> 03:07:55,620 trỏ đến cùng một bộ nhớ nếu không thì chúng ta nói Foo họ không trỏ tới point to the same memory otherwise we say Foo they don't point to 2328 03:07:55,620 --> 03:08:01,260 cùng một ký ức và sau đó bạn có thể mong đợi bạn sẽ in cái này ra bảng điều khiển the same memory and then you can expect that you get this printed to the console 2329 03:08:01,260 --> 03:08:05,880 đơn giản là vì vâng, thực ra thì r trỏ đến cùng một không gian bộ nhớ và nếu simply because yes the r actually pointing to the same memory space and if 2330 03:08:05,880 --> 03:08:09,060 bất cứ điều gì nếu dành cho những người trong số các bạn tò mò có lẽ bạn sẽ nghĩ ổn thôi any if for for those of you who are curious you'd be probably thinking okay 2331 03:08:09,060 --> 03:08:13,620 điều gì sẽ xảy ra nếu tôi thay đổi nó thành thế này và lý tưởng nhất là chúng ta sẽ gặp lỗi như what happens if I just change it to this and we should ideally get an error as 2332 03:08:13,620 --> 03:08:18,000 bạn có thể thấy ở đây và điều đó chỉ đơn giản là bởi vì chúng ta chưa thực hiện sự bình đẳng you can see in here and that is simply because we haven't implemented equality 2333 03:08:18,000 --> 03:08:23,220 trong lớp này nên người đó không tuân thủ đến sự bình đẳng ở đây và chúng ta sẽ nói chuyện nhiều hơn on this class so person doesn't conform to equality in here and we'll talk more 2334 03:08:23,220 --> 03:08:27,540 về sự bình đẳng có lẽ một chút sau nhưng nếu về cơ bản bạn muốn đảm bảo about equality perhaps a little bit later but if you wanna basically ensure 2335 03:08:27,540 --> 03:08:32,340 các thể hiện lớp của bạn là Công bằng rồi bạn phải nói Công bằng ở đây và your class instances are Equitable then you have to say Equitable in here and 2336 03:08:32,340 --> 03:08:38,220 sau đó bạn tiếp tục và Xác định một tĩnh Funk bình đẳng như thế này nhưng chúng tôi sẽ then you go ahead and Define a static Funk equal like this but we will 2337 03:08:38,220 --> 03:08:42,660 có lẽ sẽ nói về điều này một chút sau này chỉ biết rằng giá trị bằng nhau này là probably talk about this a little bit later just know that this equal equal is 2338 03:08:42,660 --> 03:08:48,540 không giống như bằng bằng bằng cái này về cơ bản kiểm tra nếu hai biến giữ not the same as equal equal this basically tests if two variables hold 2339 03:08:48,540 --> 03:08:53,580 các giá trị bên trong bằng nhau Tuy nhiên, cơ sở khác dựa trên một số logic values that internally are equal to each other base based on some logic however 2340 03:08:53,580 --> 03:08:57,960 đây là một số logic mà Swift có đã thực hiện và bạn không thực hiện điều này this is some logic that Swift has implemented and you don't implement this 2341 03:08:57,960 --> 03:09:02,160 theo logic này tất cả những gì cái này làm chỉ cần đảm bảo hai biến là in this logic at all what this one does is just make sure two variables are 2342 03:09:02,160 --> 03:09:07,560 trỏ đến cùng một cấp phát bộ nhớ được rồi và như tôi đã đề cập trước đây pointing to the same memory allocation all right and as I as I mentioned before 2343 03:09:07,560 --> 03:09:13,800 có lẽ bạn không sử dụng cái này thường xuyên bây giờ các lớp không giống cấu trúc cũng có thể you probably don't use this so often now classes unlike structures can also 2344 03:09:13,800 --> 03:09:18,240 có ý nghĩa thừa kế là bạn có thể tạo ra một siêu lớp với một số logic và have inheritance meaning that you can create a super class with some logic and 2345 03:09:18,240 --> 03:09:21,720 sau đó bạn có thể có một số lớp con khác phù hợp với điều đó thực sự không then you can have some other subclasses that conform to that actually not 2346 03:09:21,720 --> 03:09:26,160 đã xác nhận nhưng họ phân lớp đó là siêu cả lớp được rồi chúng ta hãy làm bài kiểm tra nào confirmed but they subclass that's super class all right let's have an exam have 2347 03:09:26,160 --> 03:09:30,660 hãy xem một ví dụ ở đây vì vậy chúng tôi nói xe hạng được rồi nên chúng tôi có một a look at an example in here so we say class vehicle alright so we have a 2348 03:09:30,660 --> 03:09:35,760 lớp học đơn giản và chúng tôi nói đi vroom như thế này và ở đây chúng ta tiết kiệm phòng vroom simple class and we say go vroom like this and in here we save room vroom 2349 03:09:35,760 --> 03:09:40,380 như thế này được thôi, không nhất thiết phải là bất cứ điều gì khoa học thì chúng ta like this alright doesn't necessarily have to be anything scientific then we 2350 03:09:40,380 --> 03:09:45,120 tạo một lớp ô tô nên phân lớp xe được rồi nên chúng tôi nói đó là lớp con create a car class which should subclass vehicle okay so we say it's subclasses 2351 03:09:45,120 --> 03:09:49,979 chiếc xe đó ở đây còn chiếc xe thì không có bất kỳ triển khai nào của riêng nó rồi that vehicle in here and the car doesn't have any implementation of its own then 2352 03:09:49,979 --> 03:09:53,100 bạn có thể tạo một phiên bản của ô tô như cái này you can create an instance of car like this 2353 03:09:53,100 --> 03:09:58,380 và sau đó bạn có thể nói vroom chở hàng để bạn có thể nhìn thấy ô tô mặc dù nó không có and then you can say cargo vroom so you can see car though it doesn't have an 2354 03:09:58,380 --> 03:10:04,260 triển khai nội bộ của Gover it đã kế thừa chức năng đó từ nó internal implementation of Gover it it has inherited that function from its 2355 03:10:04,260 --> 03:10:08,819 siêu lớp cụ thể là xe trong trường hợp này vì vậy hãy ghi nhớ điều đó bạn có thể có superclass namely vehicle in this case so keep that in mind you can have 2356 03:10:08,819 --> 03:10:13,680 kế thừa bằng cách sử dụng các lớp một cái gì đó mà bạn không thể làm trong inheritance using classes which is something that you cannot do in 2357 03:10:13,680 --> 03:10:20,399 cấu trúc được rồi bây giờ các lớp cũng có thể có Setters riêng để bạn thực sự có thể structures okay now classes can also have private Setters so you can actually 2358 03:10:20,399 --> 03:10:26,700 có một biến và được đánh dấu là VAR nhưng chỉ có thể được đặt riêng tư nên bạn have a variable and that is marked as VAR but can only be set privately so you 2359 03:10:26,700 --> 03:10:30,600 có thể thấy ở đây những biến này chỉ là vars đơn giản có nghĩa là chúng có thể can see in here these variables are just simple vars meaning that they can be 2360 03:10:30,600 --> 03:10:35,640 cả thay đổi nội bộ và cũng thay đổi bên ngoài bạn có thể thấy ở đây both internally changed and also externally changed you can see in here 2361 03:10:35,640 --> 03:10:40,439 giả sử Foo có tuổi 20. Tôi có thể vào đây và nói đồ ăn ở độ tuổi cộng thêm let's say Foo has the age of 20. I can go in here and say food at age plus 2362 03:10:40,439 --> 03:10:46,319 bằng 10. và với cú pháp này tôi thay đổi khá nhiều tuổi của Foo equal to 10. and with this syntax I'm pretty much changing the age of Foo so 2363 03:10:46,319 --> 03:10:51,420 nếu sau đó tôi đủ tuổi thì sẽ là 31 ở đây để bạn có thể thấy nó là một biến if I then go to full age it should be 31 in here so you can see it's a variable 2364 03:10:51,420 --> 03:10:57,540 đó có thể là cả bên ngoài Lee và đã thay đổi nội bộ rồi nên nếu bạn that can both be externally Lee and internally changed all right so if you 2365 03:10:57,540 --> 03:11:02,640 đánh dấu một số tài sản là VAR bên trong một tuy nhiên bạn cũng có thể đánh dấu một mark some a property as VAR inside a class however you can also Mark a 2366 03:11:02,640 --> 03:11:09,180 thuộc tính như VAR tuy nhiên hãy cho phép điều đó được chỉ thay đổi nội bộ trong lớp property as VAR however allow that to be only internally within the class changed 2367 03:11:09,180 --> 03:11:17,460 được rồi vậy hãy nói là lớp người hai vì vậy chúng ta nói VAR H ins được đặt riêng tư okay so let's say class person two so then we say private set VAR H ins so 2368 03:11:17,460 --> 03:11:23,100 bằng cách sử dụng các bộ riêng tư mà chúng tôi đang nói điều đó chỉ có thể được đặt bên trong by by using private sets we're saying that only can be set internally inside 2369 03:11:23,100 --> 03:11:27,720 việc triển khai lớp này và có thể đọc từ bên ngoài được rồi và sau đó this class implementation and can be read from the outside all right and then 2370 03:11:27,720 --> 03:11:34,140 chúng ta nói rằng chúng ta khởi tạo nó bằng H của int thì ta nói tự H là H được rồi và we say we initialize it with an H of int then we say self H is H all right and 2371 03:11:34,140 --> 03:11:37,260 thì chúng ta có một hàm ở đây, chúng ta nói tăng then we have a function in here we say increase 2372 03:11:37,260 --> 03:11:43,020 tăng tuổi và chúng tôi nói tuổi của bản thân là bằng cộng bằng một nên về cơ bản chúng ta là increase age and we say self-age is equal plus equal one so we're basically 2373 03:11:43,020 --> 03:11:47,220 nói khá giống logic như chúng ta đã có trước đây nhưng bây giờ bạn sẽ thấy rằng bạn saying pretty much the same logic as we had before but you'll now see that you 2374 03:11:47,220 --> 03:11:52,500 không thể thay đổi độ tuổi này từ bên ngoài triển khai lớp nên giả sử Bas là cannot change this age from outside this class implementation so let's say Bas is 2375 03:11:52,500 --> 03:11:56,700 bằng người thứ hai và rồi chúng ta nói 20 ở đây rồi chúng ta nói xấu equal to person two and then we say 20 here then we say bad 2376 03:11:56,700 --> 03:12:03,960 H Bas chấm h nếu sau đó bạn cố gắng thay đổi bên ngoài này bạn sẽ gặp lỗi H Bas dot h if you then try to change this externally you will gain an error 2377 03:12:03,960 --> 03:12:07,979 đơn giản vì tài sản này không có thể ổn định từ bên ngoài bạn có thể nhìn thấy nó simply because this property is not settable from outside you can see it 2378 03:12:07,979 --> 03:12:12,899 không thể bị thay đổi ngay bây giờ nếu bạn xóa bộ riêng tư này khỏi đây bạn can't be mutated all right now if you remove this private set from here you 2379 03:12:12,899 --> 03:12:17,399 có thể biến đổi tuổi đó từ bên ngoài như được rồi bạn có thể thấy nó đang hoạt động can mutate that age from the outside as well all right you can see it's working 2380 03:12:17,399 --> 03:12:22,560 như mong đợi nhưng nếu bạn có cú pháp bộ riêng tư thì không thể sửa đổi được as expected but if you have the syntax private set then it can't be modified 2381 03:12:22,560 --> 03:12:27,779 từ bên ngoài việc thực hiện lớp học tuy nhiên bạn vẫn có thể sử dụng cái này from outside the class implementation itself however you can use still this 2382 03:12:27,779 --> 03:12:32,100 chức năng sau đó sửa đổi điều đó biến nội bộ để bạn có thể nói xấu function which then modifies that variable internally so you can say bads 2383 03:12:32,100 --> 03:12:36,359 tăng tuổi và sau đó vượt qua bạn có thể xem bây giờ H đáng lẽ phải đổi thành 21 increase age and then passage you can see now H should have been changed to 21 2384 03:12:36,359 --> 03:12:39,600 tại đây được rồi, đó là Cú pháp cho at this all right so that's the Syntax for 2385 03:12:39,600 --> 03:12:45,720 tập riêng tư trong các lớp trong Swift bây giờ bạn cũng có thể, ý tôi là bây giờ chúng ta private set in classes in Swift now you can also I mean now that we're 2386 03:12:45,720 --> 03:12:47,819 nói về các lớp học rất quan trọng mà chúng ta đã nói đến talking about about classes very important that we talked about 2387 03:12:47,819 --> 03:12:51,300 công cụ khởi tạo cũng vì công cụ khởi tạo rất rất đặc biệt, tôi initializers as well because initializers are very very special I 2388 03:12:51,300 --> 03:12:54,840 sẽ nói trong Swift rằng bạn có thể có công cụ khởi tạo tiện lợi và bạn có thể would say in Swift in that you can have convenience initializers and you can 2389 03:12:54,840 --> 03:13:00,540 bây giờ cũng có bộ khởi tạo được chỉ định người khởi tạo được chỉ định mục tiêu của họ also have designated initializers now designated initializers their goal 2390 03:13:00,540 --> 03:13:08,220 thực sự là để đảm bảo rằng họ xây dựng một thể hiện của Lớp bằng cách really is to is to ensure that they construct an instance of the Class by 2391 03:13:08,220 --> 03:13:13,020 trước hết phải đảm bảo rằng tất cả tài sản các giá trị được thiết lập và cũng có thể first of all ensuring that all property values are set and also that the 2392 03:13:13,020 --> 03:13:18,300 cấu trúc bên trong hoặc bên trong giá trị của lớp đó giữ nguyên internal structure or the internal validity of that class holds up 2393 03:13:18,300 --> 03:13:22,800 tuy nhiên bạn cũng có thể có được sự thuận tiện công cụ khởi tạo có nghĩa là điều duy nhất however you can also have convenience initializers meaning that the only thing 2394 03:13:22,800 --> 03:13:27,300 họ làm là họ có thể thêm một số logic tới Trình xây dựng hoặc they do is that they probably add some logic to the Constructor or the 2395 03:13:27,300 --> 03:13:31,920 trình khởi tạo của lớp đó nhưng chúng về cơ bản là vào cuối ngày initializer of that class but they essentially at the end of the day 2396 03:13:31,920 --> 03:13:38,819 ủy quyền khởi tạo cho một trình khởi tạo được chỉ định nên có vẻ như bạn delegate the initialization to a designated initializer so it's as if you 2397 03:13:38,819 --> 03:13:44,040 ví dụ như bạn có cho ví dụ mẹ bạn đang ở trong bếp hoặc have for instance a you have for instance your mother in the kitchen or 2398 03:13:44,040 --> 03:13:49,319 bố của bạn đang ở trong bếp có một bữa tiệc và họ đang làm đồ ăn và sau đó your father in the kitchen there is a party and they're making food and then 2399 03:13:49,319 --> 03:13:53,760 bạn đứng ở cửa bếp như giống như một đại biểu và mọi người đến you stand at the door of the kitchen as kind of like a delegate and people come 2400 03:13:53,760 --> 03:13:59,040 và làm cho họ làm như thế họ nói về cơ bản là họ đặt hàng and make their uh make like they basically make their order they say 2401 03:13:59,040 --> 03:14:03,180 Tôi có thể lấy cái này được không, sau đó bạn có thể nói chuyện với họ bạn sẽ giống như hãy nói could I please have this then you can talk to them you'd be like let's say 2402 03:14:03,180 --> 03:14:06,479 ai đó đến trước cửa nhà bếp nói rằng tôi có thể vui lòng lấy một tách trà và someone comes to the door the kitchen says could I please get a cup of tea and 2403 03:14:06,479 --> 03:14:10,319 thì bạn có thể nói ồ, có nhất thiết phải vậy không là trà đỏ hay nó phải là trà đen then you can say oh dude does it have to be red tea or does it have to be a black 2404 03:14:10,319 --> 03:14:14,580 trà rồi họ nói ồ trà đỏ rồi bạn đi đi với bố của bạn và nói bạn có thể vui lòng tea then they say oh red tea then you go to your father and say could you please 2405 03:14:14,580 --> 03:14:19,800 tạo không khí blah blah nên thực ra tôi quên mất nó đen hay đỏ make a air blah blah so I actually forgot whether it was black or red that 2406 03:14:19,800 --> 03:14:25,439 người đó đã quyết định Nhưng bất kể họ nói rồi bạn đến gặp bố bạn và hỏi that person decided But whichever they say then you go to your father and ask 2407 03:14:25,439 --> 03:14:28,680 hoặc mẹ của bạn và yêu cầu họ làm nó vậy nên bạn giống như một đại biểu or your mother and ask them to make it so you're kind of like a delegate you're 2408 03:14:28,680 --> 03:14:32,520 làm công việc của cha hoặc mẹ bạn dễ dàng hơn một chút và đó chính xác là making the job of your father or mother a little bit easier and that's exactly 2409 03:14:32,520 --> 03:14:38,700 công cụ khởi tạo tiện lợi làm gì loại bỏ một số rắc rối và sau đó tại what a convenience initializer does it gets rid of some Hassle and then at the 2410 03:14:38,700 --> 03:14:42,359 cuối ngày nó giao phó công việc cho một trình khởi tạo được chỉ định nên chỉ end of the day it delegates the work to a designated initializer so just the 2411 03:14:42,359 --> 03:14:45,359 người khởi tạo được chỉ định là người trong nhà bếp và sự tiện lợi designated initializer is the person in the kitchen and the convenience 2412 03:14:45,359 --> 03:14:49,620 người khởi tạo bạn đang ở cửa được chứ nhưng chúng ta hãy xem một số ví dụ về initializer is you at the door okay but let's have a look at some examples of 2413 03:14:49,620 --> 03:14:53,939 điều này thực sự hoạt động như thế nào trong cuộc sống thực vậy hãy nói Tesla hạng được rồi thì chúng ta how this actually works in real life so let's say class Tesla all right then we 2414 03:14:53,939 --> 03:15:00,000 nói hãy sản xuất nhà sản xuất của tôi máy chủ là Tesla thì chúng ta nói hãy làm mô hình say let's manufacture my manufacturer server is Tesla then we say let's model 2415 03:15:00,000 --> 03:15:05,939 là một chuỗi và hãy để năm ở đó năm sản xuất được rồi is a string and let's year is in so the year production all right then 2416 03:15:05,939 --> 03:15:11,160 ừm chúng tôi sẽ khởi tạo dòng thử nghiệm của mình ở đây chúng tôi tạo một trình khởi tạo được chỉ định um we will initialize our test line here we we create a designated initializer 2417 03:15:11,160 --> 03:15:15,240 bạn có thể thấy ở đây được chỉ định nó không có sự tiện lợi được viết trước đó you can see in here is designated it doesn't have convenience written before 2418 03:15:15,240 --> 03:15:19,200 nó và chúng ta sẽ sớm nói về sự tiện lợi nhưng bất kỳ trình khởi tạo nào không có it and we'll talk about convenience soon but any initializer that doesn't have 2419 03:15:19,200 --> 03:15:23,760 từ tiện lợi trước nó là một bộ khởi tạo và các lớp được chỉ định có thể the word convenience before it is a designated initializer and classes can 2420 03:15:23,760 --> 03:15:29,580 có nhiều chỉ định và nhiều ừm, công cụ khởi tạo tiện lợi được rồi, vậy nên have multiple designated and multiple um convenience initializers all right so 2421 03:15:29,580 --> 03:15:34,620 đây là một công cụ khởi tạo được chỉ định và chúng tôi nói ở đây mô hình là X vì vậy hãy nói bằng here's a designated initializer and we say here model is X so let's say by 2422 03:15:34,620 --> 03:15:39,359 mặc định bất cứ ai khởi tạo Tesla mà không chuyển bất kỳ giá trị nào cho chúng tôi, họ default anyone initializing Tesla without passing any values to us they 2423 03:15:39,359 --> 03:15:44,100 lấy Model X Tesla và sau đó chúng tôi nói năm là năm 2023. get a Model X Tesla and then we say year is 2023. 2424 03:15:44,100 --> 03:15:49,500 vì vậy đó là một được chỉ định và chỉ định công cụ khởi tạo cái tiếp theo chúng ta sẽ nói so that's one designated and designated initializer the next one we will say 2425 03:15:49,500 --> 03:15:55,020 init và trong trình khởi tạo được chỉ định này chúng tôi thực sự lấy mô hình như một chuỗi init and in this designated initializer we actually take the model as a string 2426 03:15:55,020 --> 03:16:00,060 và năm là một số nguyên được rồi chúng tôi nói hình mẫu bản thân là một hình mẫu và and the year as an integer all right so we say self model is a model and 2427 03:16:00,060 --> 03:16:03,899 self.year là một năm được rồi self.year is a year all right 2428 03:16:03,899 --> 03:16:08,700 như thế bây giờ là một thuộc tính khác của bộ khởi tạo được chỉ định là chúng like that now another property of designated initializers is that they 2429 03:16:08,700 --> 03:16:11,700 không thể giao phó công việc của họ cho người khác cannot delegate their work to another 2430 03:16:11,700 --> 03:16:19,080 trình khởi tạo được chỉ định nên ở đây bạn có thể nói mình ở trong đó model X và năm là designated initializer so in here you can say self in it model X and year is 2431 03:16:19,080 --> 03:16:23,580 2023 nên chúng ta sẽ gặp lỗi ở đây nói rằng một trình khởi tạo được chỉ định 2023 so we should get an error in here saying that a designated initializer 2432 03:16:23,580 --> 03:16:29,040 không thể ủy thác công việc của mình cho người khác được rồi bạn có thể thấy nó không thể ủy quyền nên cannot delegate its work to another one okay you can see it cannot delegate so 2433 03:16:29,040 --> 03:16:34,140 người khởi tạo được chỉ định nên làm tất cả bản thân công việc của họ họ không thể dựa vào designated initializers should do all their work themselves they cannot rely 2434 03:16:34,140 --> 03:16:40,439 trên một trình khởi tạo được chỉ định khác được rồi vì vậy đó là dành cho công cụ khởi tạo được chỉ định on another designated initializer okay so that's for designated initializers 2435 03:16:40,439 --> 03:16:44,640 bây giờ chúng ta hãy xem xét sự tiện lợi trình khởi tạo bây giờ hãy nói rằng bạn muốn now let's have a look at a convenience initializer now let's say that you want 2436 03:16:44,640 --> 03:16:49,560 để tạo một trình khởi tạo tiện lợi theo mặc định giả định rằng năm là to create a convenience initializer that by default assumes that the year is 2437 03:16:49,560 --> 03:16:54,479 2023. vì vậy người gọi tới trình khởi tạo đó không cần phải qua năm đâu nhé 2023. so the caller to that initializer doesn't have to pass the year all right 2438 03:16:54,479 --> 03:17:01,200 vậy bạn nói tiện lợi trình khởi tạo hoặc xin lỗi init và sau đó so then you say convenience initializer or sorry init and then the 2439 03:17:01,200 --> 03:17:05,580 tài sản duy nhất chúng tôi muốn ở đây là làm mẫu được rồi và ở đây bạn có thể only property we want in here is the model all right and in here then you can 2440 03:17:05,580 --> 03:17:09,600 nói rằng chức năng này gọi bản thân trong đó với mô hình say this function calls the self in it with the model 2441 03:17:09,600 --> 03:17:14,580 được đưa ra ở đây nhưng năm là 2023 theo mặc định để bạn có thể thấy that is given in here but the year is 2023 by default so you can see a 2442 03:17:14,580 --> 03:17:19,740 trình khởi tạo tiện lợi đang ủy quyền công việc của nó đối với một trình khởi tạo được chỉ định trong convenience initializer is delegating its work to a designated initializer in 2443 03:17:19,740 --> 03:17:25,560 được rồi bây giờ bạn có thể tiếp tục và tạo một lớp con bạn có thể nói lớp a here okay now you can go ahead then and create a subclass you can say class a 2444 03:17:25,560 --> 03:17:30,240 Tesla mô hình y được rồi và nó đang phân lớp Tesla model y all right and it is subclassing 2445 03:17:30,240 --> 03:17:35,100 Tesla và trong đó có những gì bạn muốn làm bạn muốn tạo một Tesla and in its in it then what you want to do you want to create an 2446 03:17:35,100 --> 03:17:41,819 trình khởi tạo cho mô hình y theo mặc định gọi siêu khởi tạo và thiết lập initializer for model y that by default calls the super initializer and sets the 2447 03:17:41,819 --> 03:17:48,240 mô hình thành Y và đặt năm thành 2023 đúng hoặc có lẽ nó chỉ có thể gọi đây là model to Y and sets the year to 2023 all right or perhaps it could just call this 2448 03:17:48,240 --> 03:17:52,260 sự tiện lợi ở đây cũng vậy, hãy hãy xem để bạn tạo một trình khởi tạo convenience in it in here as well let's have a look so you create an initializer 2449 03:17:52,260 --> 03:17:55,560 và ở đây bạn nói Được rồi tôi muốn tất cả init đúng tuy nhiên bạn cần phải cẩn thận and here you say Okay I want an init all right however you need to be careful 2450 03:17:55,560 --> 03:18:00,960 bởi vì init đã được triển khai trên siêu lớp ở ngay đây nên nếu bạn because init is already implemented on the superclass right here so if you're 2451 03:18:00,960 --> 03:18:05,640 cũng tạo một trong và trong lớp con của bạn bạn phải thêm tiền tố vào nó bằng ghi đè also creating an in and in your subclass you have to pre prefix it with override 2452 03:18:05,640 --> 03:18:10,080 vậy bạn đang nói rằng tôi cũng đang tạo ra một phiên bản khác của cái này được và bạn có thể so you're saying I'm creating also another version of this okay and you can 2453 03:18:10,080 --> 03:18:15,000 nhìn xem nó nói bạn cần ở cuối trình khởi tạo này bằng cách nào đó gọi Super in see it it says you need to at the end of this initializer somehow call Super in 2454 03:18:15,000 --> 03:18:20,160 vậy thì chúng ta nói được rồi chúng ta gọi Super init và đối với model chúng ta nói model Y it so then we say okay then we call Super init and for model we say model Y 2455 03:18:20,160 --> 03:18:25,200 và năm là 2023. được rồi, hãy xem nào chuyện gì xảy ra ở đây and year is 2023. all right let's see what happens in here 2456 03:18:25,200 --> 03:18:29,399 được rồi bây giờ nó thực sự sẽ hoạt động như mong đợi điều này sẽ không mang lại cho bạn bất kỳ điều gì okay so now this should actually work as expected this shouldn't give you any 2457 03:18:29,399 --> 03:18:33,720 lỗi được rồi, hãy xem điều gì xảy ra nếu bạn bình luận điều này và thay vào đó errors all right let's see what happens if you comment this out and just instead 2458 03:18:33,720 --> 03:18:38,700 gọi một trong những người khởi tạo được chỉ định của chúng tôi rất xin lỗi, trình khởi tạo tiện lợi của chúng tôi call one of our designated initializers so sorry our convenience initializer 2459 03:18:38,700 --> 03:18:43,740 anh chàng này là ai đây, chúng ta vừa mới đã thông qua mô hình kể từ năm which is this guy right here we just passed the model since the Year is 2460 03:18:43,740 --> 03:18:48,180 đã được đặt thành năm 2023 một cách thuận tiện trình khởi tạo chúng ta có thể thử gọi nó already set to 2023 in this convenience initializer we could just try to call it 2461 03:18:48,180 --> 03:18:53,160 và xem điều gì xảy ra nên tôi sẽ đi nói người mẫu là y được rồi và đúng and see what happens so I'm just going to say model is y all right and right 2462 03:18:53,160 --> 03:18:57,660 ở đây vì đây là nơi được chỉ định bộ khởi tạo bên trong một thiết bị được chỉ định here since this is a designated initializer inside a designated 2463 03:18:57,660 --> 03:19:01,380 trình khởi tạo bạn không thể gọi một trình khởi tạo tiện lợi từ siêu của bạn initializer you cannot call a convenience initializer from your super 2464 03:19:01,380 --> 03:19:06,600 siêu hạng nên đây là một quy tắc khác bạn phải nhớ nên tôi nghĩ là tốt super class so this is another rule that you have to remember so I think a good 2465 03:19:06,600 --> 03:19:13,080 quy tắc cần nhớ là được chỉ định công cụ khởi tạo trong các lớp con, chúng chỉ có thể rule to remember is that designated initializers in subclasses they can only 2466 03:19:13,080 --> 03:19:17,100 gọi tới bộ khởi tạo được chỉ định trong siêu lớp call to designated initializers in their superclass 2467 03:19:17,100 --> 03:19:22,620 bên trong bất kỳ lớp nào được chỉ định trình khởi tạo không thể ủy quyền cho bất kỳ ai khác inside any class a designated initializer cannot delegate to any other 2468 03:19:22,620 --> 03:19:29,640 khởi tạo được rồi tiện lợi bộ khởi tạo có thể bên trong các lớp con và initializer okay convenience initializers can inside subclasses and 2469 03:19:29,640 --> 03:19:35,580 bên trong lớp học của riêng họ gọi một trong hai và không về cơ bản là không inside their own classes call either and no basically not either 2470 03:19:35,580 --> 03:19:39,899 nhưng họ có thể gọi một người được chỉ định trình khởi tạo được rồi, có một chút thôi but they can call a designated initializer okay it is a little bit 2471 03:19:39,899 --> 03:19:44,399 đặc biệt tôi hoàn toàn biết điều đó nhưng đó chỉ là một số quy tắc mà Swift đã đặt ra special I'm completely aware of that but it's just some rules that Swift has set 2472 03:19:44,399 --> 03:19:48,779 và tôi nghĩ về mặt logic thì chúng có ý nghĩa nhưng họ có thể biến việc lập trình thành một and I think logically they make sense but kind of they can make programming a 2473 03:19:48,779 --> 03:19:52,020 đôi khi hơi khó khăn khi bạn đang làm việc với các lớp học vậy nên hãy little bit difficult sometimes when you're working with classes so let's 2474 03:19:52,020 --> 03:19:57,420 hãy tạo một phiên bản của mô hình này y vì vậy chúng tôi nói Tesla Model Y và ở đây bạn let's create an instance of this model y so we say Tesla Model Y and in here you 2475 03:19:57,420 --> 03:20:02,640 có thể thấy chúng ta không phải chuyển bất kỳ giá trị nào vào bộ khởi tạo đơn giản vì chúng ta can see we don't have to pass any values to the initializer simply because we 2476 03:20:02,640 --> 03:20:08,640 đã có init mà không cần đầu vào về cơ bản các giá trị không có đối số được rồi already have an init with no input values basically no arguments okay then 2477 03:20:08,640 --> 03:20:16,020 chúng tôi nói mô hình y ôi mô hình y mô hình chấm và mẫu y năm đó và sau đó là mẫu y we say model y oops model y dot model and model y that year and then model y 2478 03:20:16,020 --> 03:20:21,240 nhà sản xuất dấu chấm đến từ siêu lớp luôn được đặt thành Tesla dots manufacturer which comes from the superclass which is always set to Tesla 2479 03:20:21,240 --> 03:20:25,560 được rồi bây giờ một điều mà tôi đã đề cập ở all right now one thing that I mentioned at the 2480 03:20:25,560 --> 03:20:29,939 đầu phần đó là thế các lớp là loại tham chiếu, chúng không phải beginning of the section was that classes are reference types they're not 2481 03:20:29,939 --> 03:20:35,279 các loại giá trị không giống như cấu trúc và điều đó thực sự sẽ khiến bạn nhận thức được value types unlike structures and that should really make you aware of 2482 03:20:35,279 --> 03:20:40,500 chuyển các phiên bản của lớp học của bạn tới hoạt động vì vậy chúng ta hãy nhìn vào đây passing instances of your classes to functions so let's have a look in here 2483 03:20:40,500 --> 03:20:44,939 hãy tạo một thanh foo và chúng tôi nói nó là một ví dụ về người thứ hai được rồi với let's create a foo bar and we say it's an instance of person two all right with 2484 03:20:44,939 --> 03:20:50,520 tuổi 20 ở đây và sau đó chúng ta nói Fubar chấm h và sau đó hãy nói rằng the age of 20 in here and then we say Fubar dot h and then let's say that 2485 03:20:50,520 --> 03:20:55,859 có một chức năng đang tìm kiếm vô hại nó được gọi là làm một cái gì đó tất cả there is a function that is looking harmless it's called do something all 2486 03:20:55,859 --> 03:21:01,020 đúng và với người đó và chúng tôi chỉ cần vượt qua người hai ví dụ về điều đó, anh chàng này right and with person and we just pass person two instance to it what this guy 2487 03:21:01,020 --> 03:21:05,279 bên trong người đó có phải là dấu chấm không tăng tuổi nó gọi là tăng tuổi does internally is that person dot increase age it calls increase age 2488 03:21:05,279 --> 03:21:10,500 hoạt động trên người đó được rồi Fubar hiện tại tôi 20 tuổi function on that person all right Fubar is at the moment having the age of 20 2489 03:21:10,500 --> 03:21:16,439 và sau đó nếu bạn nói làm điều gì đó với fubar rồi nói fubard.h bạn có thể thấy and then if you say do something with fubar and then say fubard.h you can see 2490 03:21:16,439 --> 03:21:22,560 tuổi sẽ được tăng lên 21. và đơn giản là vì lý do đằng sau the age will have been increased to 21. and simply is because the reason behind 2491 03:21:22,560 --> 03:21:27,359 đằng sau điều này là các lớp học các loại tham chiếu có nghĩa là bằng cách gọi it behind this is that classes are reference types meaning that by calling 2492 03:21:27,359 --> 03:21:33,600 hàm này và truyền một thể hiện của biến của bạn cho chức năng này bạn this function and passing an instance of your variable to this function you're 2493 03:21:33,600 --> 03:21:38,760 không sao chép giá trị của thanh thức ăn qua như những trường hợp mới ngoại trừ bạn thực sự not copying the values of food bar over as new instances except you're actually 2494 03:21:38,760 --> 03:21:44,520 vượt qua toàn bộ không gian bộ nhớ của bạn Xin lỗi bộ nhớ và được phân bổ cho người của bạn passing your entire memory space Sorry the memory and allocated for your person 2495 03:21:44,520 --> 03:21:49,080 2 instance vào hàm này nên cái này chức năng này hoàn toàn miễn phí để làm 2 instance into this function so this function is completely free to do 2496 03:21:49,080 --> 03:21:53,160 bất cứ điều gì nó muốn với người này ví dụ vậy nên hãy cẩn thận một chút anything it wants with this person instance so just be a little bit careful 2497 03:21:53,160 --> 03:21:57,000 với điều đó chỉ cần biết rằng các lớp học là một đặc biệt hơn một chút so với cấu trúc with that just know that classes are a little bit more special than structures 2498 03:21:57,000 --> 03:22:00,899 với các cấu trúc bạn nhận được nhiều hơn một chút có thể nói là an toàn with structures you get a little more safety so to say 2499 03:22:00,899 --> 03:22:04,380 bây giờ là một khái niệm khác và chúng ta sẽ đi để nói về điều này trước khi chúng ta kết thúc chuyện này now another concept and that we're going to talk about before we close off this 2500 03:22:04,380 --> 03:22:09,300 phần của video là phần khởi tạo lại chúng khá hữu ích trong một số trường hợp đặc biệt section of the video is de-initializers they're quite useful in some special 2501 03:22:09,300 --> 03:22:13,680 trường hợp nhưng một số trường hợp khác bạn có thể không cần chúng nên tôi sẽ nói có lẽ cases but some other cases you probably don't need them so I would say probably 2502 03:22:13,680 --> 03:22:16,979 90 percent of ties are working with classes you don't need the initializers 2503 03:22:16,979 --> 03:22:21,779 unless you're working with some sort of notifications or RX for instance and 2504 03:22:21,779 --> 03:22:24,899 yeah if you're working with reactive programming 2505 03:22:24,899 --> 03:22:29,819 so let's have a look at the initializers as their name indicates they're kind of 2506 03:22:29,819 --> 03:22:34,460 similar to initializers but they do the opposite the initializers are invoked 2507 03:22:34,460 --> 03:22:40,140 automatically by Swift whenever your class instance is going out of memory so 2508 03:22:40,140 --> 03:22:44,100 it's kind of getting cleaned from the memory so no one else is holding on to 2509 03:22:44,100 --> 03:22:48,960 it and it has to be removed from memory so let's create a my class in here okay 2510 03:22:48,960 --> 03:22:54,359 then in the init and we will just say initialized and then we'll have a 2511 03:22:54,359 --> 03:22:58,800 function here called do something which which is empty at the moment all right 2512 03:22:58,800 --> 03:23:03,540 then we create a new function in here called D in it and you can see that it 2513 03:23:03,540 --> 03:23:06,720 is purple in here but it doesn't matter I mean the color doesn't really matter 2514 03:23:06,720 --> 03:23:11,160 it just matters that this is a reserved word it's a keyword in Swift meaning 2515 03:23:11,160 --> 03:23:14,220 that you can't really use it anywhere else except if you do something like 2516 03:23:14,220 --> 03:23:17,700 funky like that but just know that there's a reserved word it's it's 2517 03:23:17,700 --> 03:23:21,479 similar to in it but it's just called when your class is going out of scope 2518 03:23:21,479 --> 03:23:26,819 and in here we can say d initialized all right now to test this we should 2519 03:23:26,819 --> 03:23:30,600 actually create a function in which we create an instance of this because if 2520 03:23:30,600 --> 03:23:35,279 you create an instance of your class in here let's just say let's my class is an 2521 03:23:35,279 --> 03:23:41,640 instance of my class and then my class do something where the initializer won't 2522 03:23:41,640 --> 03:23:46,080 probably be invoked you can see your initializer is invoked uh do something I 2523 03:23:46,080 --> 03:23:49,800 mean in here we could actually say do something just so that we see that that 2524 03:23:49,800 --> 03:23:54,000 function is also invoked however Danish Lancer isn't embodian that's just the 2525 03:23:54,000 --> 03:24:00,120 nature of uh of playgrounds so what you could do is to create a closure my 2526 03:24:00,120 --> 03:24:05,460 closure and we say it is this it is basically carrying out this 2527 03:24:05,460 --> 03:24:11,040 logic inside the closure and then we can call our closure so at the end of this 2528 03:24:11,040 --> 03:24:15,180 closure this variable should go out of scope meaning that it's the initializer 2529 03:24:15,180 --> 03:24:19,920 should be called so let's say my closure in here all right and then you can see 2530 03:24:19,920 --> 03:24:24,479 your D initializer oopsie Daisy what happened my closure 2531 03:24:24,479 --> 03:24:29,640 uh all right cannot find my did I spell it incorrectly like this 2532 03:24:29,640 --> 03:24:34,200 and now you can see that the initializer is in fact called and invoked simply 2533 03:24:34,200 --> 03:24:38,819 because after my closure is called this scope completely finishes meaning that 2534 03:24:38,819 --> 03:24:43,620 all variables inside this scope should also go out of scope so dnits will be 2535 03:24:43,620 --> 03:24:49,500 called on all class instances all right really good we seem to now be done 2536 03:24:49,500 --> 03:24:55,500 actually with classes so um let's just jump right ahead into the 2537 03:24:55,500 --> 03:25:00,479 next concept and that is protocols so I'm going to go in here and actually not 2538 03:25:00,479 --> 03:25:03,660 there we don't have to go there I'm just going to press command n in here create 2539 03:25:03,660 --> 03:25:08,580 a new playground and we're going to say protocols again ensure that it is inside 2540 03:25:08,580 --> 03:25:12,000 your workspace and in not inside another playground 2541 03:25:12,000 --> 03:25:16,920 create all right and we get rid of this Explorer in here and we say Foundation 2542 03:25:16,920 --> 03:25:23,220 like this Foundation all right now protocols for those of you who are rust 2543 03:25:23,220 --> 03:25:27,120 developers you probably already know what protocols are and Protocols are 2544 03:25:27,120 --> 03:25:31,800 special kind of objects kind of like interfaces you could say in Java for 2545 03:25:31,800 --> 03:25:37,880 instance I'm not sure the term in kotlin what that is but you also have protocols 2546 03:25:37,880 --> 03:25:45,359 as mixings in Dart for instance so what protocols are is that you create 2547 03:25:45,359 --> 03:25:51,300 an interface you create a set of rules that objects which conform to a protocol 2548 03:25:51,300 --> 03:25:56,220 have to follow so it is not a class and because if you 2549 03:25:56,220 --> 03:25:59,700 have a class for instance if you have a super class that has some functions all 2550 03:25:59,700 --> 03:26:04,859 subclasses do not have to re-implement that function however if you have a 2551 03:26:04,859 --> 03:26:09,779 protocol that only creates some functions with no body so the functions 2552 03:26:09,779 --> 03:26:14,520 don't have logic in them any object that conforms to those protocols have to 2553 03:26:14,520 --> 03:26:20,520 implement those functions by themselves all right so it is actually a little bit 2554 03:26:20,520 --> 03:26:25,200 difficult to explain what protocols are without having a look at how they work 2555 03:26:25,200 --> 03:26:30,060 so let's go in here and say that this is automatically running and create our 2556 03:26:30,060 --> 03:26:35,220 first protocol so we create a protocol called can breathe okay 2557 03:26:35,220 --> 03:26:39,660 and in here we say any object that can breathe should have a function called 2558 03:26:39,660 --> 03:26:44,520 breathe so you can see this function is special functioning it has no body you 2559 03:26:44,520 --> 03:26:49,200 cannot create for instance a class person and just have this in it this 2560 03:26:49,200 --> 03:26:54,000 just won't work you have to have a function body and you can't do that 2561 03:26:54,000 --> 03:26:59,460 either in structures your function has to have a body so you can see that won't 2562 03:26:59,460 --> 03:27:03,000 work in structures either that's why Protocols are a little bit special in 2563 03:27:03,000 --> 03:27:06,660 that they can have just function declarations without any implementation 2564 03:27:06,660 --> 03:27:10,920 all right and that's what is called interface insomni in so many other 2565 03:27:10,920 --> 03:27:15,840 languages all right so we have a protocol now can breathe 2566 03:27:15,840 --> 03:27:21,000 let's go ahead and create a structure called animal and we saw when we when we 2567 03:27:21,000 --> 03:27:23,939 were talking about structures that structures cannot have super classes so 2568 03:27:23,939 --> 03:27:27,540 they cannot actually inherit from each other okay so if you create for instance 2569 03:27:27,540 --> 03:27:33,960 a structure of animal and then you say struct cat you cannot say that cat is an 2570 03:27:33,960 --> 03:27:39,120 animal it just won't work structures don't allow inheritance however they do 2571 03:27:39,120 --> 03:27:44,520 allow inheritance from protocols so you can say a structure of animal that 2572 03:27:44,520 --> 03:27:49,620 inherits from can breathe and this is completely fine Swift syntax however 2573 03:27:49,620 --> 03:27:53,100 we're getting an error because now you can see it says the animal a type 2574 03:27:53,100 --> 03:27:56,700 doesn't conform to protocol can't breathe and the reason behind that is 2575 03:27:56,700 --> 03:28:00,960 that a protocol here called can't breathe specifies that anyone conforming 2576 03:28:00,960 --> 03:28:04,739 to this protocol has to implement this particular function and we haven't done 2577 03:28:04,739 --> 03:28:09,720 that so as soon as we go and type breathing here you can see then this 2578 03:28:09,720 --> 03:28:16,319 error will go away because now animal uh character conforms to Cambridge protocol 2579 03:28:16,319 --> 03:28:22,140 okay and in here we can just say animal breathing like this okay 2580 03:28:22,140 --> 03:28:26,819 and also then you can create another structure struct person can breathe like 2581 03:28:26,819 --> 03:28:33,000 this and in here we say breathe as well and then we say person breathing like 2582 03:28:33,000 --> 03:28:37,380 that all right so then you can go ahead and create instances of these two 2583 03:28:37,380 --> 03:28:42,600 structures we say dog is an animal and we say dog breathe and then we create a 2584 03:28:42,600 --> 03:28:48,239 person called Foo an instance of person we say the food breathe all right now 2585 03:28:48,239 --> 03:28:52,620 you can see both of these lines will then be invoked uh simply because we 2586 03:28:52,620 --> 03:28:58,260 call them from here so that's basically the essence of how protocols work I mean 2587 03:28:58,260 --> 03:29:03,359 protocols can be a lot more complicated than that actually uh in that I mean we 2588 03:29:03,359 --> 03:29:07,859 talked right now about having protocols that only have function declarations but 2589 03:29:07,859 --> 03:29:12,060 not implementations but protocols and Swift are kind of like mix-ins and dart 2590 03:29:12,060 --> 03:29:17,819 in that they can't actually have their own implementations so they're not just 2591 03:29:17,819 --> 03:29:22,739 like objects that have dummy function headers but they can indeed have 2592 03:29:22,739 --> 03:29:26,100 function implementations so let's have a look at that let's create a protocol 2593 03:29:26,100 --> 03:29:32,880 called protocol can jump and then we say a jump function all right then in order 2594 03:29:32,880 --> 03:29:36,960 to create implementation for this function I mean you may be thinking okay 2595 03:29:36,960 --> 03:29:41,880 maybe I should do this jumping and this will just give you an error because you 2596 03:29:41,880 --> 03:29:46,260 cannot create your function body inside the Proto call itself the trick to do 2597 03:29:46,260 --> 03:29:50,399 that is to go ahead and create an extension on can jump okay and we 2598 03:29:50,399 --> 03:29:54,300 haven't talked about extensions yet but it is necessary that we just name it in 2599 03:29:54,300 --> 03:29:58,140 here simply because that's the way to actually add implementation to this 2600 03:29:58,140 --> 03:30:02,399 function all right then we go and say okay it's the same function and then we 2601 03:30:02,399 --> 03:30:07,020 just say jumping so by this trick you I mean it's not 2602 03:30:07,020 --> 03:30:14,279 really a trick this is the way to do it by using this uh technique I'm trying to 2603 03:30:14,279 --> 03:30:18,300 avoid saying trick by using this technique you're adding a default 2604 03:30:18,300 --> 03:30:22,080 implementation to this otherwise very dumb function 2605 03:30:22,080 --> 03:30:26,160 so you may be asking okay but what happened here can I just call this 2606 03:30:26,160 --> 03:30:32,279 function now so can I just say can jump is an instance of can jump can I do that 2607 03:30:32,279 --> 03:30:37,739 well you can't because you cannot instantiate a protocol you need to 2608 03:30:37,739 --> 03:30:40,560 instantiate an object that conforms the protocol 2609 03:30:40,560 --> 03:30:45,779 okay such as a cat that can jump so let's say struct cat and jump and now 2610 03:30:45,779 --> 03:30:49,800 since this jump function already has an implementation you can see that we're 2611 03:30:49,800 --> 03:30:54,359 not getting an error from Swift saying cats should implement this function if 2612 03:30:54,359 --> 03:30:58,020 you remove this implementation from here all of a sudden all objects that conform 2613 03:30:58,020 --> 03:31:02,340 to can jump need to implement this jump function themselves but if you bring it 2614 03:31:02,340 --> 03:31:06,899 back into can jump then all objects that conform to that protocol will get this 2615 03:31:06,899 --> 03:31:10,920 implementation by default but they can go ahead and change it if they want to 2616 03:31:10,920 --> 03:31:15,540 like this okay so that's also valid however if you 2617 03:31:15,540 --> 03:31:19,979 leave it it also works with that problem so let's create an instance of this cat 2618 03:31:19,979 --> 03:31:24,739 we say Whiskers Whiskers it's an instance of cat and we can just say 2619 03:31:24,739 --> 03:31:29,279 whiskers.jump all right this is how we can invoke that function that is 2620 03:31:29,279 --> 03:31:36,300 implemented on can jump right now protocols apart from defining 2621 03:31:36,300 --> 03:31:42,540 function headers that they're conforming objects have to implement they can also 2622 03:31:42,540 --> 03:31:48,120 Define variables let's let's go ahead in here and say we have a protocol in here 2623 03:31:48,120 --> 03:31:55,140 we say protocol has name protocol has a name and then in here we say VAR 2624 03:31:55,140 --> 03:32:01,020 name a string and then we have to say gets in here or set or both like this 2625 03:32:01,020 --> 03:32:06,000 now what this really means is that this protocol is asking Swift saying any 2626 03:32:06,000 --> 03:32:12,300 object that com conforms to me has to have a variable called name that has to 2627 03:32:12,300 --> 03:32:17,220 at least have a getter what does this mean well this is really just a dumb way 2628 03:32:17,220 --> 03:32:22,500 of saying this so it it basically says a variable that 2629 03:32:22,500 --> 03:32:27,420 at least I can read from but this syntax isn't valid and protocols I wish it was 2630 03:32:27,420 --> 03:32:31,859 but you have to implement them like this so you're basically saying a some sort 2631 03:32:31,859 --> 03:32:35,460 of a variable that I can read from which is called name all right and then you 2632 03:32:35,460 --> 03:32:40,859 can also have H all right and let's just say h should be getter and Setter 2633 03:32:40,859 --> 03:32:44,640 meaning that it should actually be a variable that can be set all right now 2634 03:32:44,640 --> 03:32:49,920 we can go ahead in here and say we have a struct of dog and it has a name you 2635 03:32:49,920 --> 03:32:53,580 can now see that we'll get an error now from Swift saying that this doesn't 2636 03:32:53,580 --> 03:32:57,779 conform to has name and we can ask it to fix it for us and you can see by default 2637 03:32:57,779 --> 03:33:01,439 it creates these variables for us however what I really don't like about 2638 03:33:01,439 --> 03:33:07,140 this is that what it did is that it created a variable for name so it could 2639 03:33:07,140 --> 03:33:13,319 actually be a let since the protocol has name asks for this variable to be at 2640 03:33:13,319 --> 03:33:19,380 least and at most actually in read-only so we can just demote this to a let's 2641 03:33:19,380 --> 03:33:24,359 variable and you'll see that everything will work as expected okay so let's go 2642 03:33:24,359 --> 03:33:27,120 ahead in here and then create an instance of this dog 2643 03:33:27,120 --> 03:33:32,399 and we can call this instance woof let's say woof is an instance of dark and we 2644 03:33:32,399 --> 03:33:38,279 say name is with an H is a very graceful ten then we say 2645 03:33:38,279 --> 03:33:45,239 with that name all right and with that H wolf dot h plus equal one so we just 2646 03:33:45,239 --> 03:33:50,819 increase the age but we cannot change the name all right so let's just woof 2647 03:33:50,819 --> 03:33:54,600 agent here as well so let's see what happens okay and this I mean we're 2648 03:33:54,600 --> 03:33:58,140 getting these errors right here because we can't modify woof because it's an 2649 03:33:58,140 --> 03:34:02,640 instance of a structure which by default becomes a left constant that cannot even 2650 03:34:02,640 --> 03:34:06,899 have a mutation internally so we have to change this to A4 so remember structures 2651 03:34:06,899 --> 03:34:12,060 are different from classes all right so this is basically a protocol that 2652 03:34:12,060 --> 03:34:17,819 required all its uh classes or structures that conform to it to have a 2653 03:34:17,819 --> 03:34:22,560 variable call name that can at least and at most be read from so it can be a let 2654 03:34:22,560 --> 03:34:27,899 and it can also be a VAR but why does it have to be a VAR a promotion of let if 2655 03:34:27,899 --> 03:34:31,200 we don't have to have it as a bar because the protocol says I should just 2656 03:34:31,200 --> 03:34:35,220 be able to get from it now you may be thinking okay but why do we do these 2657 03:34:35,220 --> 03:34:39,600 things well the reason is if you want to go ahead and add functionality to this 2658 03:34:39,600 --> 03:34:44,220 protocol then this protocol internally has access to name and age let's say 2659 03:34:44,220 --> 03:34:50,100 extension has name and then we can then create a function that says describe me 2660 03:34:50,100 --> 03:34:57,899 then we can see we can say you your name is name and you are 2661 03:34:57,899 --> 03:35:04,020 age years old okay so since this protocol expects a 2662 03:35:04,020 --> 03:35:10,680 name variable and an age variable and it can then go ahead and read them so it 2663 03:35:10,680 --> 03:35:14,279 can access them and it should also be able to set them okay and then you can 2664 03:35:14,279 --> 03:35:20,340 say func increase age and in here then you can say self h plus equal one and we 2665 03:35:20,340 --> 03:35:24,479 can fix this actually now so you can basically go ahead and add 2666 03:35:24,479 --> 03:35:30,960 functionality to your protocols let's say fix it and we add a mutating 2667 03:35:30,960 --> 03:35:35,460 function in here so you can see this protocol since it knows what it requires 2668 03:35:35,460 --> 03:35:40,080 all its uh classes and structures that conform to it have to have these values 2669 03:35:40,080 --> 03:35:45,000 then it can go ahead and take advantage of those variables or functions or 2670 03:35:45,000 --> 03:35:49,020 whatever it has okay so now all of a sudden all objects are conformed to have 2671 03:35:49,020 --> 03:35:53,760 has the name protocol will get a describe me function let's go ahead in 2672 03:35:53,760 --> 03:35:58,800 here and say woof you can see it has a describe me function all of a sudden and 2673 03:35:58,800 --> 03:36:04,979 it will say oops okay here your name is woof and you are 11 years 2674 03:36:04,979 --> 03:36:08,340 old okay and maybe this should actually return a string 2675 03:36:08,340 --> 03:36:12,540 and it could just return that string instead of printing it here and in here 2676 03:36:12,540 --> 03:36:15,840 then we get the result you can see it says your name is Wolf and you're 11 2677 03:36:15,840 --> 03:36:22,020 years old and then since we have a VAR with uh pointing to a structure we can 2678 03:36:22,020 --> 03:36:27,600 go ahead and say woof dot increase age and then we say wolf h all right so the 2679 03:36:27,600 --> 03:36:32,760 H by this point is 11 and then we in we invoke this increased age function which 2680 03:36:32,760 --> 03:36:38,279 is mutating function and then we get the age of 12 all right so protocols can 2681 03:36:38,279 --> 03:36:44,040 Define kind of um constraints or kind of like an interface on objects that 2682 03:36:44,040 --> 03:36:49,620 conform to them and therefore can using extensions on those protocols can access 2683 03:36:49,620 --> 03:36:53,760 those variables and functions which are placed in here so it's kind of like 2684 03:36:53,760 --> 03:36:57,600 giving a blueprint so it's kind of like any object that conforms to me has has 2685 03:36:57,600 --> 03:37:01,920 to have this blueprint and then I can internally use that blueprint to my 2686 03:37:01,920 --> 03:37:06,600 advantage okay now just we've just like we've seen this 2687 03:37:06,600 --> 03:37:10,739 in here protocols can have mutating functions something that I want to 2688 03:37:10,739 --> 03:37:14,460 mention next but I think I just mentioned a little bit too early perhaps 2689 03:37:14,460 --> 03:37:18,899 but at least you get the point let's now focus on that mutating function so if 2690 03:37:18,899 --> 03:37:22,620 you say protocol vehicle I just want to show you another example 2691 03:37:22,620 --> 03:37:27,479 and let's say we have a variable speed and we say it should be an integer which 2692 03:37:27,479 --> 03:37:31,800 is getter and Setter so we should be able to set it and read from it okay 2693 03:37:31,800 --> 03:37:38,340 then we create a mutating function here increase speed and we say buy which 2694 03:37:38,340 --> 03:37:44,460 value like this okay so we Define this mutating function here and then we go 2695 03:37:44,460 --> 03:37:49,739 ahead and extend this vehicle like this and we implement this mutating 2696 03:37:49,739 --> 03:37:53,819 function all right so what we did here was a little bit um is not optimal 2697 03:37:53,819 --> 03:37:58,739 because we implemented a mutating func increased age inside the extension so 2698 03:37:58,739 --> 03:38:02,580 whoever looks at our protocol won't immediately understand that there is a 2699 03:38:02,580 --> 03:38:05,520 mutating funk available on it so if you wanted to make this code a little bit 2700 03:38:05,520 --> 03:38:09,979 more readable we would place this function a declaration here as well okay 2701 03:38:09,979 --> 03:38:15,720 so let's go in our code again and we say in the implementation of our protocol 2702 03:38:15,720 --> 03:38:19,739 increase speed by value will actually have an implementation that's a 2703 03:38:19,739 --> 03:38:26,220 self.speed is plus equal to Value like that and we can bring this value down 2704 03:38:26,220 --> 03:38:29,460 here to make the code a little bit more readable as well 2705 03:38:29,460 --> 03:38:33,479 and perhaps decrease the size of the preview as well 2706 03:38:33,479 --> 03:38:38,760 so let's then go ahead and create for instance a a concrete implementation of 2707 03:38:38,760 --> 03:38:44,160 this vehicle protocol so we say struct bike and then bike it will have a speed 2708 03:38:44,160 --> 03:38:49,680 oh let's actually move this and say it is a vehicle all right then we get an 2709 03:38:49,680 --> 03:38:53,580 error from uh Swift saying that it doesn't conform to Vehicles simply 2710 03:38:53,580 --> 03:39:00,540 because it didn't have the speed variable then inside this bike we create 2711 03:39:00,540 --> 03:39:06,479 an init and we say self dot speed is zero you could have also done it like 2712 03:39:06,479 --> 03:39:09,899 this that also works it kind of depends on 2713 03:39:09,899 --> 03:39:14,399 how you like to implement and do your implementations I've seen both and for 2714 03:39:14,399 --> 03:39:19,140 me both are fine it's up to you and your team to actually make a decision on what 2715 03:39:19,140 --> 03:39:24,359 uh can what convention you want to use for initializing your variables and 2716 03:39:24,359 --> 03:39:28,200 structures okay but this is completely valid syntax as well 2717 03:39:28,200 --> 03:39:31,439 after doing that let's create an instance of this byte let's say bike is 2718 03:39:31,439 --> 03:39:36,660 an instance of bike like this then we get the current speed it should be zero 2719 03:39:36,660 --> 03:39:41,760 because that's what the initializer did then we say bike increase speed by 10 2720 03:39:41,760 --> 03:39:46,560 and then we say bike speed all right so because we are conforming to the vehicle 2721 03:39:46,560 --> 03:39:53,100 protocol we can have access to this increased speed function in here now I 2722 03:39:53,100 --> 03:39:57,060 can see we're getting an error simply because a bike cannot be mutated you can 2723 03:39:57,060 --> 03:40:01,680 see we're actually invoking a mutating function on an immutable let constant 2724 03:40:01,680 --> 03:40:06,600 and the solution to that is to change this to VAR all right now you can see 2725 03:40:06,600 --> 03:40:10,680 our speed was zero and then it was increased to 10 simply because we 2726 03:40:10,680 --> 03:40:16,140 increased it using this mutating function defined and implemented on the 2727 03:40:16,140 --> 03:40:21,180 vehicle protocol all right so that's one thing I mean that's not 2728 03:40:21,180 --> 03:40:23,819 one thing that's quite a lot of things about protocols but at least you get the 2729 03:40:23,819 --> 03:40:30,060 idea of protocols now protocols can also be used as a conformance uh how do you 2730 03:40:30,060 --> 03:40:35,100 say it blueprints kind of so let me just explain how this would work 2731 03:40:35,100 --> 03:40:41,700 you can at any point in Swift use the is syntax or a keyword in order to check 2732 03:40:41,700 --> 03:40:46,260 whether an object conforms to a protocol or not because any class or any 2733 03:40:46,260 --> 03:40:53,880 structure can conform to at least one and actually not at least at least zero 2734 03:40:53,880 --> 03:40:59,279 and at most unlimited number of protocols so a structural class doesn't 2735 03:40:59,279 --> 03:41:03,060 have to conform to any protocol or it can conform to one or more protocols 2736 03:41:03,060 --> 03:41:07,260 that's what I'm trying to say and if you want to at any point check whether an 2737 03:41:07,260 --> 03:41:11,880 object conforms to a protocol you can use the is syntax let's have a look at 2738 03:41:11,880 --> 03:41:16,080 that let's say we create a function called describe and it takes an object 2739 03:41:16,080 --> 03:41:20,340 of type any and we haven't talked about this before but any is pretty much as 2740 03:41:20,340 --> 03:41:26,580 its name indicates any object okay then we say if object is a vehicle then we 2741 03:41:26,580 --> 03:41:33,060 say uh object conforms to their vehicle protocol 2742 03:41:33,060 --> 03:41:42,540 else object does not conform to the to the vehicle protocol all right then we 2743 03:41:42,540 --> 03:41:47,819 can go ahead and call this describe function and describe our object of bike 2744 03:41:47,819 --> 03:41:52,800 and then you can see since by conforms to the vehicle protocol then we get this 2745 03:41:52,800 --> 03:41:59,520 printed to the screen however if we had a structure of warm or at work warm and 2746 03:41:59,520 --> 03:42:07,140 it didn't conform to the vehicle protocol and we sit warm as an instance 2747 03:42:07,140 --> 03:42:13,939 of warm and then we just say describe more then you can see that we will get 2748 03:42:13,939 --> 03:42:19,859 this message printed to the screen object does not conform all right so now 2749 03:42:19,859 --> 03:42:22,920 that we've done that let's just remove this warm I don't like to have worms in 2750 03:42:22,920 --> 03:42:27,239 my coat so at least you get the point now with 2751 03:42:27,239 --> 03:42:33,359 with that as well now there's one more uh one more thing 2752 03:42:33,359 --> 03:42:38,520 that we have to talk about when it comes to protocols and that is I mean we've 2753 03:42:38,520 --> 03:42:45,300 talked about is but we haven't talked about as and as with a question mark and 2754 03:42:45,300 --> 03:42:48,660 they make more sense when we when we've already talked about optionals and we 2755 03:42:48,660 --> 03:42:52,500 haven't talked about optionals yet we'll talk about optionalism in like the next 2756 03:42:52,500 --> 03:42:56,580 three sections of this video but I just want to name it as well so you know that 2757 03:42:56,580 --> 03:43:01,859 it exists in Swift so using this as syntax you can 2758 03:43:01,859 --> 03:43:09,180 conditionally promote an object to a specific type so in here you can see 2759 03:43:09,180 --> 03:43:15,239 object is vehicle and if you say object dot you don't have any anything to do 2760 03:43:15,239 --> 03:43:18,479 now with this I mean you cannot do anything with this object even though 2761 03:43:18,479 --> 03:43:23,640 you actually said if object is a vehicle then I kind of would expect us to be 2762 03:43:23,640 --> 03:43:27,779 able to invoke these functions on that vehicle because we actually asked Swift 2763 03:43:27,779 --> 03:43:33,420 is it a vehicle then we come here but Swift doesn't understand the syntax as 2764 03:43:33,420 --> 03:43:38,939 good as it understands as like this and the reason behind that is You're simply 2765 03:43:38,939 --> 03:43:44,279 just doing an if statement in here saying is it that then do something but 2766 03:43:44,279 --> 03:43:50,040 you didn't actually promote this object to that type all right so any is like a 2767 03:43:50,040 --> 03:43:54,359 very low object type however this is sitting a lot higher in the hierarchy 2768 03:43:54,359 --> 03:43:59,399 and that's the reason we say promote so let me actually show you an example 2769 03:43:59,399 --> 03:44:05,220 let's say that we have uh that we have let's say a bike in here 2770 03:44:05,220 --> 03:44:09,300 and bike is a vehicle which has increased speed all right but we want to 2771 03:44:09,300 --> 03:44:14,700 create a function that that can allow any object to come in and if that object 2772 03:44:14,700 --> 03:44:20,520 is a vehicle kind of like this then it will increase its speed by 20. all right 2773 03:44:20,520 --> 03:44:26,399 so let's say funk increase speed if vehicle 2774 03:44:26,399 --> 03:44:31,800 and then the parameter to this is an object of type any all right then in 2775 03:44:31,800 --> 03:44:38,580 here we say if then we create a VAR and the vehicle is equal to this object and 2776 03:44:38,580 --> 03:44:43,739 then we say is it a vehicle like this with an as syntax if 2777 03:44:43,739 --> 03:44:48,300 it is then we say vehicle speed you see now we get access to all properties of 2778 03:44:48,300 --> 03:44:53,520 that vehicle because we promoted this object to a vehicle so it's not similar 2779 03:44:53,520 --> 03:44:57,660 to is because this won't allow us to access 2780 03:44:57,660 --> 03:45:01,920 the vehicle objects and hear our Properties or functions then we say get 2781 03:45:01,920 --> 03:45:06,300 the current speed vehicle increase the speed by 10 and then get the speed again 2782 03:45:06,300 --> 03:45:14,939 in here okay otherwise we say this was not a vehicle so let's then go ahead in 2783 03:45:14,939 --> 03:45:19,920 here and see what happens so let's say increase speed 2784 03:45:19,920 --> 03:45:25,140 if vehicle and then we pass our bike in here all right let's see what happens 2785 03:45:25,140 --> 03:45:30,479 are we getting a lot of Errors perhaps from Swift it crashed no okay so you can 2786 03:45:30,479 --> 03:45:36,960 see we got the value of 10 in here okay and then we get the value of 20. right 2787 03:45:36,960 --> 03:45:41,040 here okay now you may be thinking about what 2788 03:45:41,040 --> 03:45:46,080 happened in here bike let's have a look at bike you can see its speed it was 2789 03:45:46,080 --> 03:45:51,239 zero in here and then 10. and then we call this function which should have 2790 03:45:51,239 --> 03:45:56,520 increased the speed to 20. but if in here we say bike speed what happens do 2791 03:45:56,520 --> 03:46:01,859 you think it's 20 well no it is 10 actually and the reason behind that is 2792 03:46:01,859 --> 03:46:05,700 that bike is an instance if you go back to it is an instance of a structure 2793 03:46:05,700 --> 03:46:11,340 called bike so it's a structure structures are value types meaning that 2794 03:46:11,340 --> 03:46:15,000 when you call this function with an instance of your bike you're not 2795 03:46:15,000 --> 03:46:18,960 actually passing the memory consumed by this bike as a reference to this 2796 03:46:18,960 --> 03:46:22,500 function what are your what are your in fact doing is that you're making a copy 2797 03:46:22,500 --> 03:46:26,939 actually not you directly but Swift is doing it doing that Swift is making an 2798 03:46:26,939 --> 03:46:31,260 entire copy of this is making a copy of this entire object and passing it in 2799 03:46:31,260 --> 03:46:38,100 here so in here this VAR actually is pointing to not the same memory address 2800 03:46:38,100 --> 03:46:41,580 that bike is consuming but it's pointing to a completely new variable in the 2801 03:46:41,580 --> 03:46:46,319 memory and is allowing it to basically be increased by a certain speed which is 2802 03:46:46,319 --> 03:46:52,260 not affecting the spike however if this bike was an instance of a class so if we 2803 03:46:52,260 --> 03:46:57,439 went in here and said bike is actually a class let's say class now you can see 2804 03:46:57,439 --> 03:47:02,160 calling this function it will actually change the speed for you to 20. so 2805 03:47:02,160 --> 03:47:07,800 calling this function it affects the actual instance of bike itself see the 2806 03:47:07,800 --> 03:47:10,800 speed is exactly the same but if you go back to a struct you can see the speed 2807 03:47:10,800 --> 03:47:15,479 of your bike will be 10. all right so keep that in mind when you're working 2808 03:47:15,479 --> 03:47:19,380 with protocols protocols and classes and structures together go really hand in 2809 03:47:19,380 --> 03:47:25,380 hand to create amazing object oriented applications in Swift but they can make 2810 03:47:25,380 --> 03:47:29,399 things also a little bit complicated so keep that in mind when you're working 2811 03:47:29,399 --> 03:47:33,420 with these um with these Concepts 2812 03:47:33,420 --> 03:47:38,399 good that's quite enough about protocols now that we've talked enough about 2813 03:47:38,399 --> 03:47:43,140 protocols let's go ahead and talk about extensions you've already seen examples 2814 03:47:43,140 --> 03:47:48,180 of extensions and how they work in Swift but we haven't really focused on them so 2815 03:47:48,180 --> 03:47:52,859 let's do that now let's go oh I don't have to do that let's create a new 2816 03:47:52,859 --> 03:47:58,500 playground playground and in here we say blank playground and we say extensions 2817 03:47:58,500 --> 03:48:04,680 all right like that and here as well then we say create 2818 03:48:04,680 --> 03:48:10,020 and just like usual we say we just need foundation for now all right 2819 03:48:10,020 --> 03:48:16,680 so extensions as their name indicates they can add functionality to existing 2820 03:48:16,680 --> 03:48:22,620 types they can extend existing types so let's have a look at an example let's 2821 03:48:22,620 --> 03:48:27,899 say that we have an extension on data type of integer and then we say we have 2822 03:48:27,899 --> 03:48:34,200 a function called plus two which returns an integer and since this function is an 2823 03:48:34,200 --> 03:48:41,279 extension of int self in here refers to the current integer instance okay then 2824 03:48:41,279 --> 03:48:46,680 we say we return self plus two all right then we can go ahead and say 2 is equal 2825 03:48:46,680 --> 03:48:51,479 to value of 2 and then we say 2 plus 2 and then you can see then we get the 2826 03:48:51,479 --> 03:48:58,200 value of 4 here in our playground okay so self inside extensions refers to the 2827 03:48:58,200 --> 03:49:02,880 current instance meaning that this two in this case all right so self in here 2828 03:49:02,880 --> 03:49:08,399 is actually two so if you just print self and then you say return self 2829 03:49:08,399 --> 03:49:13,680 self plus two you can see self is indeed the value of 2 in here which is what 2830 03:49:13,680 --> 03:49:17,460 you've specified here so if you change that self will change to that as well 2831 03:49:17,460 --> 03:49:23,279 all right so keep that in mind that's one example of an extension 2832 03:49:23,279 --> 03:49:29,100 Now using extensions you can also add initializers to existing types which is 2833 03:49:29,100 --> 03:49:33,300 one of the most powerful features of extensions in Swift let's have a look at 2834 03:49:33,300 --> 03:49:37,200 an example let's say that you create a structure called person in here and you 2835 03:49:37,200 --> 03:49:42,420 have a first name string and then let's last name last 2836 03:49:42,420 --> 03:49:47,460 name as a string okay now what you want to do is to create a I mean you want to 2837 03:49:47,460 --> 03:49:52,979 behold and sorry you want to hold on to this person's Constructor or initializer 2838 03:49:52,979 --> 03:49:56,340 that Swift already creates for you with the first name and last name so you 2839 03:49:56,340 --> 03:50:01,739 don't want to change that but you also want a Constructor that takes in a full 2840 03:50:01,739 --> 03:50:06,600 name however if you go in here and say init full name screen 2841 03:50:06,600 --> 03:50:10,800 then you can see all of a sudden your person doesn't have any other 2842 03:50:10,800 --> 03:50:14,640 Constructor with a first name and last name anymore your only Constructor 2843 03:50:14,640 --> 03:50:19,319 inside the structure itself will replace the existing Constructor okay and that's 2844 03:50:19,319 --> 03:50:23,460 not good so what you want if you want to for instance have a Constructor 2845 03:50:23,460 --> 03:50:28,920 initializer on this person that doesn't replace the existing in initializer that 2846 03:50:28,920 --> 03:50:32,700 Swift creates for you then you need to create an extension on person 2847 03:50:32,700 --> 03:50:37,200 and then you go ahead and add your initializer in here okay now you can see 2848 03:50:37,200 --> 03:50:40,560 if you try to initialize an instance of person you have both of these 2849 03:50:40,560 --> 03:50:44,580 Constructors the default one that Swift created for you and also your own 2850 03:50:44,580 --> 03:50:49,560 Constructor which is inside the extension all right so let's inside this 2851 03:50:49,560 --> 03:50:53,580 Constructor go ahead and grab the components out of this full name so we 2852 03:50:53,580 --> 03:50:57,660 say full name components is a function and we separate 2853 03:50:57,660 --> 03:51:04,680 the components by space all right and so we say let components and then we want 2854 03:51:04,680 --> 03:51:08,760 to pass these values that we extract from components so we say self in it 2855 03:51:08,760 --> 03:51:15,420 into our Constructor then we say the first name is actually components first 2856 03:51:15,420 --> 03:51:21,120 otherwise fully and we say in here as last name is components last otherwise 2857 03:51:21,120 --> 03:51:26,880 fully just like that all right so this is very dumb implementation to be honest 2858 03:51:26,880 --> 03:51:30,899 with you but I mean it's not too dumb either it is literally taking the first 2859 03:51:30,899 --> 03:51:34,140 part of a name and the last part of a name assuming that this is the first 2860 03:51:34,140 --> 03:51:37,979 name and this is the last name and anything that is between them separated 2861 03:51:37,979 --> 03:51:41,760 by space is the middle name which we don't care about in this instance okay 2862 03:51:41,760 --> 03:51:47,700 then we can go and create an instance of person so left person is a person then 2863 03:51:47,700 --> 03:51:51,960 you can see we have both Constructors or initializers and we're going to use full 2864 03:51:51,960 --> 03:51:55,920 name in here we say Foo and bar you can see they're separated by space and the 2865 03:51:55,920 --> 03:52:00,000 first component is Foo and last name and last components bar then we say person 2866 03:52:00,000 --> 03:52:05,479 first name and person dot last name all right so that's another powerful future 2867 03:52:05,479 --> 03:52:11,100 of extensions in Swift in that you can extend an existing structure for 2868 03:52:11,100 --> 03:52:16,279 instance and add a new Constructor or initializer to it okay 2869 03:52:16,279 --> 03:52:23,100 now apart from that you can also extend existing types and add conformance to a 2870 03:52:23,100 --> 03:52:27,180 protocol to an existing type so that's also really cool so let's create a 2871 03:52:27,180 --> 03:52:32,220 protocol in here we call it Goes Vroom okay so that's our protocol name 2872 03:52:32,220 --> 03:52:37,260 and this protocol what it does is that it has a VAR room value and it's a 2873 03:52:37,260 --> 03:52:41,760 string and it should we should be able to read from it okay and then we create 2874 03:52:41,760 --> 03:52:46,920 a function we say go vroom and then this function returns a string now we go 2875 03:52:46,920 --> 03:52:52,319 ahead and extend our goes room and then we add the default implementation for 2876 03:52:52,319 --> 03:52:58,080 this go vroom function and then we say self Dot vroomvalue 2877 03:52:58,080 --> 03:53:02,220 goes room so remember this is just a variable that 2878 03:53:02,220 --> 03:53:05,819 we know any instance conforming to our protocol should have access to and then 2879 03:53:05,819 --> 03:53:08,700 here we're just adding the default implementation for this code firm 2880 03:53:08,700 --> 03:53:13,080 function and returning this string as its return value all right then we go 2881 03:53:13,080 --> 03:53:18,000 and create a car instance we say struct car and this car conforms actually we 2882 03:53:18,000 --> 03:53:23,939 don't want to conform yet and in here we say let's manufacture is a string and we 2883 03:53:23,939 --> 03:53:29,040 say let's model is a string as well I guess this is just a simple car 2884 03:53:29,040 --> 03:53:34,439 structure then we can say let model X is an 2885 03:53:34,439 --> 03:53:41,100 instance of car with the manufacture of Tesla and its model is going to be X 2886 03:53:41,100 --> 03:53:45,420 and after creating this instance we can go ahead and actually extend this model 2887 03:53:45,420 --> 03:53:51,660 X so we can say model X extension sorry extension of car then we say car now all 2888 03:53:51,660 --> 03:53:57,060 of a sudden conforms to the Goes Vroom protocol you will get an errand here 2889 03:53:57,060 --> 03:54:00,960 telling you that you're not actually conforming to go Gold's room and the 2890 03:54:00,960 --> 03:54:03,960 reason behind it is that if you go to ghost room you can see that we have two 2891 03:54:03,960 --> 03:54:08,640 requirements one is that we have any type conforming to goes from protocol 2892 03:54:08,640 --> 03:54:15,420 has to have a variable called room value that's at at most and at least readable 2893 03:54:15,420 --> 03:54:19,140 uh however Carr doesn't have that and that's the error that we're getting in 2894 03:54:19,140 --> 03:54:22,920 here so let's just get Swift to fix it and you can see it creates a computer 2895 03:54:22,920 --> 03:54:27,840 property in here called vroom value which should return a string okay and 2896 03:54:27,840 --> 03:54:33,720 for our vroom value we're going to say it is self manufacturer model 2897 03:54:33,720 --> 03:54:39,720 and self.model all right and then all of a sudden this car instance conforms to 2898 03:54:39,720 --> 03:54:44,220 That Goes Vroom protocol meaning that this model X all of a sudden gets a 2899 03:54:44,220 --> 03:54:48,660 function called go vroom and if you do that you can see it says Tesla Model X 2900 03:54:48,660 --> 03:54:54,540 goes room and that's because vroom value is a variable that is implemented on all 2901 03:54:54,540 --> 03:54:58,859 types that conform to God's room but ghost room doesn't really know what this 2902 03:54:58,859 --> 03:55:03,060 value actually is it just extracts that value and adds it here and then says 2903 03:55:03,060 --> 03:55:08,220 goods room however it is the conforming types responsibility to return this 2904 03:55:08,220 --> 03:55:13,020 value and in this case the case of car structure we're just saying manufacture 2905 03:55:13,020 --> 03:55:19,439 and then model X so it says Tesla Model X goes through this part is provided by 2906 03:55:19,439 --> 03:55:23,160 conforming types such as car and this part is provided by the ghost room 2907 03:55:23,160 --> 03:55:29,340 protocol itself okay so you can also have I mean now now that 2908 03:55:29,340 --> 03:55:32,640 we've talked about that let's go to the next concept and that is having 2909 03:55:32,640 --> 03:55:37,620 extensions on classes and with convenience initializers so you can 2910 03:55:37,620 --> 03:55:42,180 actually extend existing data types and add convenience initializers to classes 2911 03:55:42,180 --> 03:55:46,439 and not structures because structures don't have convenience initializers but 2912 03:55:46,439 --> 03:55:49,920 classes can so let's go ahead in here and create a 2913 03:55:49,920 --> 03:55:54,960 class and we call it my double so like a class that holds on to a double variable 2914 03:55:54,960 --> 03:56:00,960 and we say VAR value double and then we can say an initializer that 2915 03:56:00,960 --> 03:56:05,279 takes a value of double and we say self value is value in here okay 2916 03:56:05,279 --> 03:56:09,479 now you can go ahead then is actually this I don't think this needs to be a 2917 03:56:09,479 --> 03:56:14,939 VAR it can just be a let perhaps okay and in here then we're going to go ahead 2918 03:56:14,939 --> 03:56:20,279 and create a convenience initializer and which always sets this value to zero if 2919 03:56:20,279 --> 03:56:23,819 anyone initializes the instance of My Double because at the moment if we say 2920 03:56:23,819 --> 03:56:29,699 let let's go ahead Foo is my double you can 2921 03:56:29,699 --> 03:56:33,859 see that you always have to have a value available and pass to my double 2922 03:56:33,859 --> 03:56:38,340 initializer but if you don't want to have that you can extend your my double 2923 03:56:38,340 --> 03:56:43,500 class in here and say you have a convenience in it in here that takes no 2924 03:56:43,500 --> 03:56:49,020 parameters and calls self in it with a value of zero so this is literally 2925 03:56:49,020 --> 03:56:53,279 delegating its task to a designated initializer in the my double class but 2926 03:56:53,279 --> 03:56:56,880 it is a convenience initializer that is created inside an extension so you 2927 03:56:56,880 --> 03:57:01,319 that's one of the powers of extensions you can extend an existing class and add 2928 03:57:01,319 --> 03:57:06,840 a new convenience initializer okay so then you can go ahead and say my 2929 03:57:06,840 --> 03:57:10,500 double to create an instance of it and then you can just say value all right 2930 03:57:10,500 --> 03:57:14,819 you can see now the value is zero this is another fancy way I'm of basically 2931 03:57:14,819 --> 03:57:18,960 accessing the value you could have said let my double is an instance 2932 03:57:18,960 --> 03:57:22,680 of My Double and then you could have said my double dot value so that those 2933 03:57:22,680 --> 03:57:28,500 two lines of code work pretty much I mean achieving the same thing okay 2934 03:57:28,500 --> 03:57:33,739 now apart from extending I mean not apart from but I mentioned that 2935 03:57:33,739 --> 03:57:39,420 extensions can extend structures and classes but guess what they can also 2936 03:57:39,420 --> 03:57:46,020 extend existing protocols so so you can see in here we have a protocol called 2937 03:57:46,020 --> 03:57:50,640 ghost room and it has this go room function you can go ahead and extend it 2938 03:57:50,640 --> 03:57:55,620 you can say extension goes room and then in here you can add a new 2939 03:57:55,620 --> 03:58:01,500 function say go of room room even more okay so this is just a ridiculous name 2940 03:58:01,500 --> 03:58:05,640 I'm completely aware of it but you can um what I'm trying to say is that you 2941 03:58:05,640 --> 03:58:10,680 can extend an existing protocol as well and add new functionality to it and by 2942 03:58:10,680 --> 03:58:14,819 doing this every data type that conforms to that protocol would get your new 2943 03:58:14,819 --> 03:58:18,960 function by default so you don't have to do anything okay then in here we just 2944 03:58:18,960 --> 03:58:25,739 say self room value is vrooming even more like that okay 2945 03:58:25,739 --> 03:58:30,660 then all of a sudden model X that we created in here which conforms to which 2946 03:58:30,660 --> 03:58:34,979 is an instance of car which conforms To Go's room gets this new functionality by 2947 03:58:34,979 --> 03:58:41,399 default so then we can say Model X go vroom vroom even more and then you 2948 03:58:41,399 --> 03:58:46,140 can see that value being printed to the screen as well is rooming even more okay 2949 03:58:46,140 --> 03:58:52,260 so extensions are I would say one of the most fun aspects of any programming 2950 03:58:52,260 --> 03:58:56,399 language and in Dart for instance they're called mixins as well and 2951 03:58:56,399 --> 03:58:59,760 they're available in some other languages such as rust as well so 2952 03:58:59,760 --> 03:59:05,100 they're really fun because they allow you to make existing things and types 2953 03:59:05,100 --> 03:59:10,260 better they can kind of get out of hand sometimes if you're like misusing them 2954 03:59:10,260 --> 03:59:13,859 in that when you're extending generics types for instance you can just go crazy 2955 03:59:13,859 --> 03:59:18,180 with generics but as long as you're comfortable and you and your teammates 2956 03:59:18,180 --> 03:59:22,979 are comfortable with those extensions I would say go for it now we've talked 2957 03:59:22,979 --> 03:59:27,600 enough about extensions for now at least let's go ahead and start talking about 2958 03:59:27,600 --> 03:59:32,220 generics which is a topic a lot of developers try to avoid but I think you 2959 03:59:32,220 --> 03:59:36,779 need to embrace it because if you look at most modern toolkits and Frameworks 2960 03:59:36,779 --> 03:59:40,560 such as Swift UI they could have not been made possible 2961 03:59:40,560 --> 03:59:46,920 without generics Swift UI is pretty much based entirely on generic types so I'd 2962 03:59:46,920 --> 03:59:50,760 say one of the best practices of becoming a better developer is to 2963 03:59:50,760 --> 03:59:55,319 embrace generics learn how to use them learn how not to use them and truly 2964 03:59:55,319 --> 04:00:00,060 don't be scared of them so practice practice until you get the concepts and 2965 04:00:00,060 --> 04:00:05,580 then use them wherever you think and your teammates think makes sense 2966 04:00:05,580 --> 04:00:09,180 so without further Ado let's start talking about generic so I'm just going 2967 04:00:09,180 --> 04:00:15,000 to press command in here and say a playground and we say generics 2968 04:00:15,000 --> 04:00:19,500 like this and ensure you're creating it inside your workspace so Swift crash 2969 04:00:19,500 --> 04:00:23,279 course and we create this generics uh 2970 04:00:23,279 --> 04:00:28,140 playground import foundation and we say automatically run this all right I'm 2971 04:00:28,140 --> 04:00:34,560 going to get rid of the export to the left hand side now generix is for me at 2972 04:00:34,560 --> 04:00:41,040 least it's used to avoid writing the same function multiple times or writing 2973 04:00:41,040 --> 04:00:45,180 the same code multiple times all right now 2974 04:00:45,180 --> 04:00:48,920 generics they kind of look a little bit strange 2975 04:00:48,920 --> 04:00:52,979 but they really at the end of the day once 2976 04:00:52,979 --> 04:00:57,420 you've written the code for generics you can use them in so many different ways 2977 04:00:57,420 --> 04:01:03,720 and you will be amazed by how powerful they are okay so what we're going to do 2978 04:01:03,720 --> 04:01:07,620 as the first example of generics I'm actually gonna jump right in and write 2979 04:01:07,620 --> 04:01:11,640 kind of like a scary looking function all right but what this function is 2980 04:01:11,640 --> 04:01:16,460 trying to achieve is that I mean its mission statement is kind of like this 2981 04:01:16,460 --> 04:01:23,160 it wants to expect any numer any numerical data such as a floating value 2982 04:01:23,160 --> 04:01:27,479 or double value or an integer two of those values so it takes a left hand 2983 04:01:27,479 --> 04:01:32,880 side and a right hand side and it expects us to pass it a function that 2984 04:01:32,880 --> 04:01:37,979 can perform an operation on those two values and return a new value in 2985 04:01:37,979 --> 04:01:46,560 response such as let's say x x is 10 and let's Y is 20 and then we say let's C is 2986 04:01:46,560 --> 04:01:51,840 equal to X Plus y so this plus function takes a left hand side and a right hand 2987 04:01:51,840 --> 04:01:57,060 side and returns a result which is the equivalent of adding those two values 2988 04:01:57,060 --> 04:02:01,080 right now you can have minus in here you can 2989 04:02:01,080 --> 04:02:06,600 have division in here it can have multiplication oops if I can write it so 2990 04:02:06,600 --> 04:02:09,899 all these functions take a left hand side and a right hand side so they do 2991 04:02:09,899 --> 04:02:13,739 some operations and they're actually operators we've talked about operators 2992 04:02:13,739 --> 04:02:20,520 before okay so let's say then we create a function we say a function that 2993 04:02:20,520 --> 04:02:24,800 performs a task and we say 2994 04:02:24,800 --> 04:02:30,960 it's an operator that takes an integer and an integer and returns an integer 2995 04:02:30,960 --> 04:02:36,420 kind of like this okay and then oops and then we say it 2996 04:02:36,420 --> 04:02:43,800 performs this operation on a value on left hand side of type int and 2997 04:02:43,800 --> 04:02:50,340 and right hand side of type int and then in itself returns int okay so you can 2998 04:02:50,340 --> 04:02:53,340 see it's performing an operation that actually does the job I think they 2999 04:02:53,340 --> 04:02:56,640 actually did something like this when we were talking about operators and we 3000 04:02:56,640 --> 04:03:01,080 actually put this as a trailing closure I remember but it's similar to that at 3001 04:03:01,080 --> 04:03:05,520 least and internally what it does is calls that op function and passes the 3002 04:03:05,520 --> 04:03:09,840 left hand side and right hand side to it and returns this value in return 3003 04:03:09,840 --> 04:03:15,479 then you can go ahead and say perform Plus on 10 3004 04:03:15,479 --> 04:03:21,060 and 20. and then you can see it will just say 30 as a result because this is 3005 04:03:21,060 --> 04:03:25,800 actually a function all right and you can say plus and then you can say minus 3006 04:03:25,800 --> 04:03:29,100 of course you can say multiplication in here 3007 04:03:29,100 --> 04:03:32,760 and you could also say division in here okay 3008 04:03:32,760 --> 04:03:37,680 so maybe we could say 20. and 10 in here for the division so that 3009 04:03:37,680 --> 04:03:40,439 we get proper values printed to the console 3010 04:03:40,439 --> 04:03:44,760 so this is an example of this function now your teammate comes to you and says 3011 04:03:44,760 --> 04:03:49,800 could you make this function work with doubles as well then be like um okay 3012 04:03:49,800 --> 04:03:54,660 then I'm gonna change this to double and this two double 3013 04:03:54,660 --> 04:03:58,739 and then this to double and then you have to go and change this to double and 3014 04:03:58,739 --> 04:04:04,199 this to double and this to double then your code kind of works all right 3015 04:04:04,199 --> 04:04:09,600 but the result of these is actually now a double so if you look at Foods data 3016 04:04:09,600 --> 04:04:13,560 type is a double what happened to your integers well you change the function 3017 04:04:13,560 --> 04:04:18,720 signature from int to double and you lost the ability to work with integers 3018 04:04:18,720 --> 04:04:24,300 then you'd be like okay then I need two functions one for integer m one for 3019 04:04:24,300 --> 04:04:30,300 double then you call this perform int so we say let's see if I can change this 3020 04:04:30,300 --> 04:04:34,979 name perform int and then you say okay I'm smart enough I go ahead and create a 3021 04:04:34,979 --> 04:04:40,739 perform double and I make sure that this double works with doubles okay so 3022 04:04:40,739 --> 04:04:45,180 whoever wants to work with doubles calls perform double and whoever wants to work 3023 04:04:45,180 --> 04:04:51,300 with integers works with uh perform int then your third colleague comes and says 3024 04:04:51,300 --> 04:04:57,420 okay but I want to work with CG float and which is another data type which is 3025 04:04:57,420 --> 04:05:01,859 inside the core Graphics framework which we haven't worked with right now but you 3026 04:05:01,859 --> 04:05:05,720 can say core graphics and then you can say let X is CG 3027 04:05:05,720 --> 04:05:10,020 CG float is equal to one it's kind of like a double actually 3028 04:05:10,020 --> 04:05:15,180 and then you say oh a CG float then I have to create another perform function 3029 04:05:15,180 --> 04:05:20,160 which is called perform CG flow however as you can see this is not a 3030 04:05:20,160 --> 04:05:25,500 very maintainable way of working so this will just increase the size of your code 3031 04:05:25,500 --> 04:05:28,920 base and you have to constantly go ahead and add new functions to your 3032 04:05:28,920 --> 04:05:32,040 application wouldn't it be really good if we could 3033 04:05:32,040 --> 04:05:35,279 create a function that works with any numerical type 3034 04:05:35,279 --> 04:05:41,040 and if you look at integer let's go to anything here and then we see signed 3035 04:05:41,040 --> 04:05:45,660 integer and then side numeric you can see that this sine numeric protocol 3036 04:05:45,660 --> 04:05:50,520 conforms to another protocol which is called numeric okay and if you have a 3037 04:05:50,520 --> 04:05:58,080 double value let's say let's X is a double 1.1 if you go to double and let's 3038 04:05:58,080 --> 04:06:03,060 say numeric there should be an extension on double 3039 04:06:03,060 --> 04:06:08,460 extension double which makes it conform to a 3040 04:06:08,460 --> 04:06:13,380 that's numerical type as well so let's say binary floating point I think and 3041 04:06:13,380 --> 04:06:16,979 then expressible by Flo oops not that long perhaps 3042 04:06:16,979 --> 04:06:24,500 by integer literal hashable so stridable it is one of these implementations 3043 04:06:24,500 --> 04:06:30,000 which conforms double to add that numerical type that we were 3044 04:06:30,000 --> 04:06:33,060 just talking about I'm not sure which one it is we have to dig deep inside 3045 04:06:33,060 --> 04:06:37,439 Swift source code basically but what I'm trying to say is that both 3046 04:06:37,439 --> 04:06:45,479 double uh and int conform to a protocol called a numeric numeric 3047 04:06:45,479 --> 04:06:50,460 now if we could somehow in here say that this function works with any numerical 3048 04:06:50,460 --> 04:06:55,080 data type that would be really good so let's change this to numeric 3049 04:06:55,080 --> 04:07:01,140 and then we say numeric numeric and here here and here okay 3050 04:07:01,140 --> 04:07:05,880 now you'll see what happens inside your sift code and Swift tells you okay I 3051 04:07:05,880 --> 04:07:10,199 understand you want to work with the numerics but you can't just add them 3052 04:07:10,199 --> 04:07:15,359 like that you can't just say that this function expects numerics numeric is a 3053 04:07:15,359 --> 04:07:20,520 protocol and if you want to use it here you have to use generics so the way to 3054 04:07:20,520 --> 04:07:25,439 use generics is that you go right after your function name and you just open 3055 04:07:25,439 --> 04:07:30,840 these less than an equal signs kind of like in here then you designate a letter 3056 04:07:30,840 --> 04:07:35,699 usually a letter but sometimes people use words as well but it is very very 3057 04:07:35,699 --> 04:07:41,100 common to use a letter so you say Okay I want to represent numeric with a letter 3058 04:07:41,100 --> 04:07:45,120 okay I can't just say new American here because that is an existing data type 3059 04:07:45,120 --> 04:07:51,479 let's just say n okay as a numeric then you say n should conform to numeric data 3060 04:07:51,479 --> 04:07:55,920 type or protocol then anywhere inside your function signature where you're 3061 04:07:55,920 --> 04:08:02,279 using numeric just type n okay so in here in here right there 3062 04:08:02,279 --> 04:08:07,199 there and also here and also for the return value of your function 3063 04:08:07,199 --> 04:08:11,939 all right so now you see all of these errors are going to go away so you can 3064 04:08:11,939 --> 04:08:17,580 see all of them went away and your function still works and if I say let X 3065 04:08:17,580 --> 04:08:22,560 and then I look at the data type for X you can see X it is understood to be an 3066 04:08:22,560 --> 04:08:27,540 integer but how you didn't say anywhere that you're working with integers 3067 04:08:27,540 --> 04:08:32,160 and that's the power of generics the compiler is uh is basically inferring 3068 04:08:32,160 --> 04:08:37,620 the data type based on the values you pass here so if you say 10 and 20 then 3069 04:08:37,620 --> 04:08:41,460 it knows that they both are integers and the result should be an integer and 3070 04:08:41,460 --> 04:08:46,140 let's change this actually it's not perform int anymore it is perform okay 3071 04:08:46,140 --> 04:08:54,779 now if you go and do and let's say let's X is perform on 10.1 and 20.2 all of a 3072 04:08:54,779 --> 04:08:59,819 sudden X is a double because compiler understood that oh these both values are 3073 04:08:59,819 --> 04:09:04,199 actually double they're not integers anymore so it substitutes the return 3074 04:09:04,199 --> 04:09:09,120 value which is indicated by this n generic value to the actual values you 3075 04:09:09,120 --> 04:09:13,500 pass through this function in here okay and you can also go ahead in here and 3076 04:09:13,500 --> 04:09:17,580 say 10.1 and 20 what do you think X is going to be now 3077 04:09:17,580 --> 04:09:21,960 well the compiler is also intelligent enough to promote the value the return 3078 04:09:21,960 --> 04:09:28,859 value to the more complex or more complete data type the more complete and 3079 04:09:28,859 --> 04:09:33,420 precise data type in this case is not integer but it is actually double so if 3080 04:09:33,420 --> 04:09:39,600 you look at the data type for X is indeed double all right so that was the 3081 04:09:39,600 --> 04:09:45,960 first example of using generics in Swift and I know it could look a little bit 3082 04:09:45,960 --> 04:09:50,160 complicated but the more you work with generics you the more you will actually 3083 04:09:50,160 --> 04:09:55,020 appreciate them we've now seen this example I would say 3084 04:09:55,020 --> 04:10:01,319 actually a quite a simple example of generics in Swift now when you have 3085 04:10:01,319 --> 04:10:05,520 functions that have multiple generic parameters in this case we have just one 3086 04:10:05,520 --> 04:10:09,199 generic parameter that we've called n of type numeric 3087 04:10:09,199 --> 04:10:14,580 but in other functions you might have generic parameters maybe two two or 3088 04:10:14,580 --> 04:10:19,319 three of them or even more in that case the function signature might be getting 3089 04:10:19,319 --> 04:10:25,739 quite long you would say R is something and D is something else so looking at 3090 04:10:25,739 --> 04:10:29,520 this function you you would probably just get a panic attack just looking at 3091 04:10:29,520 --> 04:10:34,080 the function signature and that is why Swift allows you to create function 3092 04:10:34,080 --> 04:10:37,500 signatures for or generic function signatures where the direct generic 3093 04:10:37,500 --> 04:10:44,580 parameters are stated at the end of the function declaration itself and right 3094 04:10:44,580 --> 04:10:49,199 after actually the return type so to demonstrate how that works as well let's 3095 04:10:49,199 --> 04:10:53,760 just take this that we have in here the code that we have in here and let's go 3096 04:10:53,760 --> 04:10:58,560 and paste it right there okay and we will just name this function and perform 3097 04:10:58,560 --> 04:11:01,979 two and change all these instances to perform two just to ensure that 3098 04:11:01,979 --> 04:11:07,020 everything is working as expected so in order to create a function or generic 3099 04:11:07,020 --> 04:11:10,439 function where the generic parameters are defined at the anode function 3100 04:11:10,439 --> 04:11:14,760 signature you have to remove this generate type right here or as many as 3101 04:11:14,760 --> 04:11:19,859 generic types as you have you remove them from the beginning or attached to a 3102 04:11:19,859 --> 04:11:25,140 function name and you go right after the return value and then Define them right 3103 04:11:25,140 --> 04:11:32,040 there using a word clause so in here we then say where for instance n is numeric 3104 04:11:32,040 --> 04:11:38,640 so this is an alternative way of creating a generic signatures for your 3105 04:11:38,640 --> 04:11:43,380 um or for your functions and in here you would of course you would still have n 3106 04:11:43,380 --> 04:11:48,720 in there but you don't actually tag and as a meaning of type numeric so this is 3107 04:11:48,720 --> 04:11:53,279 just a an alternative way of doing it and some developers prefer this way 3108 04:11:53,279 --> 04:11:58,920 simply because in here you could just say A B C D or your generic types and at 3109 04:11:58,920 --> 04:12:04,260 the end you could actually say what those a b and c and d are in fact of 3110 04:12:04,260 --> 04:12:09,120 type of all right so just keep it in mind it's it's a it's an alternative way 3111 04:12:09,120 --> 04:12:13,800 of defining your generic functions and it will just perform exactly the same 3112 04:12:13,800 --> 04:12:21,359 way it did in the previous example okay now any data types such as a class and 3113 04:12:21,359 --> 04:12:25,080 actually I can't say any data but classes and structures in Swift can 3114 04:12:25,080 --> 04:12:29,399 conform to multiple protocols they don't necessarily have to conform only to one 3115 04:12:29,399 --> 04:12:35,220 protocol okay and using this you can basically create generics that are 3116 04:12:35,220 --> 04:12:39,899 um that are conformant to multiple multiple types so let's have a look at 3117 04:12:39,899 --> 04:12:45,359 that right now and let's create and let's create let's say that we 3118 04:12:45,359 --> 04:12:49,319 create two protocols in here we say protocol can jump okay and then in here 3119 04:12:49,319 --> 04:12:54,000 we have a function that says jump so any type that conforms to can jump should 3120 04:12:54,000 --> 04:12:57,120 have a jump function and then we create another another protocol in here that we 3121 04:12:57,120 --> 04:13:04,260 say can run okay and can run has to have a run function then we go ahead and 3122 04:13:04,260 --> 04:13:09,359 create a structure in here we call person and we say it can jump and it can 3123 04:13:09,359 --> 04:13:15,600 run like that all right so this is conform conforming a new structure to 3124 04:13:15,600 --> 04:13:21,660 two different protocols we can get a swift to fix these functions up for us 3125 04:13:21,660 --> 04:13:24,660 in here you can see in run we say running 3126 04:13:24,660 --> 04:13:30,660 and in Jump we say jumping jumping okay I think the indentation was a little bit 3127 04:13:30,660 --> 04:13:36,060 wrong all right now we have that now let's say that you want to create a 3128 04:13:36,060 --> 04:13:42,300 function called jump and run okay so let's say flunk jump 3129 04:13:42,300 --> 04:13:47,760 and run and you want to take in a value in here of some type you you want to say 3130 04:13:47,760 --> 04:13:53,399 Okay I want some value to be of any type and in here I want to say value jump and 3131 04:13:53,399 --> 04:13:58,979 value the run but since this value at the moment is of type any it cannot have 3132 04:13:58,979 --> 04:14:04,080 the ability to invoke that function jump or the Run function so you could say 3133 04:14:04,080 --> 04:14:10,620 Okay I want value to be of type can jump if you do this then you can do the jump 3134 04:14:10,620 --> 04:14:14,760 function but you can't do the run function all right so in here what you 3135 04:14:14,760 --> 04:14:18,840 need to do is to go ahead and Define a generic data type in here let's say t 3136 04:14:18,840 --> 04:14:26,160 and we say this data type can run can jump and can run like this and then 3137 04:14:26,160 --> 04:14:30,660 inside the function signature itself you say the value is of type T now you can 3138 04:14:30,660 --> 04:14:35,640 see if you type value you have access to jump and run functions so this is a way 3139 04:14:35,640 --> 04:14:39,899 of combining multiple protocols in order to create a generic function signature 3140 04:14:39,899 --> 04:14:45,540 where you have access to not only one protocol data but also multiple as long 3141 04:14:45,540 --> 04:14:49,739 as basically you can make this as long as you want to all right 3142 04:14:49,739 --> 04:14:53,399 so then we can go ahead in here and create an instance of person we say 3143 04:14:53,399 --> 04:14:57,899 person is an instance of person and then we can say jump 3144 04:14:57,899 --> 04:15:03,479 and run with the value of person and we can actually change this values internal 3145 04:15:03,479 --> 04:15:08,520 sorry external parameter type to nothing so we can just say jump and run person 3146 04:15:08,520 --> 04:15:13,620 in here okay now you can also have extensions on 3147 04:15:13,620 --> 04:15:18,720 generic types and one generic type that is very useful is actually we haven't 3148 04:15:18,720 --> 04:15:22,319 talked about them so much about their arrays and I raise you to find them like 3149 04:15:22,319 --> 04:15:27,720 this you could say let names for instance is Foo and bar now if you look 3150 04:15:27,720 --> 04:15:32,580 at the data type for names you can see it is an array of string so it is 3151 04:15:32,580 --> 04:15:38,060 denoted by these square brackets now you can actually look at if you just type 3152 04:15:38,060 --> 04:15:43,800 this is a string in here and let's see if you can find the data type for array 3153 04:15:43,800 --> 04:15:47,760 so if you say array of strings so this is this is a an alternative way of 3154 04:15:47,760 --> 04:15:51,540 writing the same same text instead of this you can just do syntactic sugar 3155 04:15:51,540 --> 04:15:55,140 here and say array of string now if you go to array you can see it is a 3156 04:15:55,140 --> 04:15:58,800 structure and it is a generic structure basically it's working with a generic 3157 04:15:58,800 --> 04:16:03,899 argument called element now you can also create extensions on 3158 04:16:03,899 --> 04:16:07,920 generic types so by simply saying extension Offspring You're basically 3159 04:16:07,920 --> 04:16:13,620 extending an array of string and this is new format actually there's a new syntax 3160 04:16:13,620 --> 04:16:18,120 in the latest Swift versions previously you have to say extension array where 3161 04:16:18,120 --> 04:16:23,040 element was equal to string so this is the old 3162 04:16:23,040 --> 04:16:26,880 syntax but the new syntax you can just simply extend an array of string which 3163 04:16:26,880 --> 04:16:30,960 is a lot more readable okay then what you can do in here since you already 3164 04:16:30,960 --> 04:16:36,120 have you've told the Swift compiler that you're extending an array of string if 3165 04:16:36,120 --> 04:16:39,479 you create a function let's say we want to create a function on our on any array 3166 04:16:39,479 --> 04:16:44,399 of string that finds the longest string okay so we say longest string and we 3167 04:16:44,399 --> 04:16:48,359 return an optional string we haven't talked about optionals yet so just for 3168 04:16:48,359 --> 04:16:52,260 now know that this means that we can either return actually have we talked 3169 04:16:52,260 --> 04:16:57,060 about options structures enumerations protocols extensions closures no we 3170 04:16:57,060 --> 04:17:00,779 haven't yet we will talk about optional soon okay but just know that this means 3171 04:17:00,779 --> 04:17:06,000 it can either be a value or it can be the lack of a value equal to nil all 3172 04:17:06,000 --> 04:17:10,439 right so and the reason behind is that you can always have and the reason I 3173 04:17:10,439 --> 04:17:16,319 mean this is an optional string is that any array like final names is an array 3174 04:17:16,319 --> 04:17:21,420 of string in here it can actually be empty okay so if this array is empty how 3175 04:17:21,420 --> 04:17:25,680 can you find the late at the longest string in this array well you can't 3176 04:17:25,680 --> 04:17:30,899 there are no strings in here okay finally it should be let right so the 3177 04:17:30,899 --> 04:17:33,239 reason this is optional is because of that 3178 04:17:33,239 --> 04:17:37,560 and then what you can do in here is to say let dot 3179 04:17:37,560 --> 04:17:40,979 um so you sorry you say self-sorted and this is I mean to be honest you don't 3180 04:17:40,979 --> 04:17:45,300 have to know exactly how this is working and this is just an example okay so we 3181 04:17:45,300 --> 04:17:49,020 say sorted and then we say left hand side string 3182 04:17:49,020 --> 04:17:54,899 and then we say right hand side string and we want to say left hand sides count 3183 04:17:54,899 --> 04:17:58,859 the number of characters in the left hand side should be more than the right 3184 04:17:58,859 --> 04:18:02,580 hand size characters and then we say take the first argument you can see the 3185 04:18:02,580 --> 04:18:07,620 first argument is then deduced to be of type string as simply because we are 3186 04:18:07,620 --> 04:18:12,180 extending a generic type whose elements are of type string and if you look at 3187 04:18:12,180 --> 04:18:17,819 this property you can see it is using the same generic type call Elements all 3188 04:18:17,819 --> 04:18:22,560 right so that's also extending generate types and then you can go ahead in here 3189 04:18:22,560 --> 04:18:27,020 and say let's say we create an array of strings we say Foo 3190 04:18:27,020 --> 04:18:33,779 bar and bads in here has one string and then Cox in here then we say longest 3191 04:18:33,779 --> 04:18:39,720 string all right then we can get the value of bar and pass it to the console 3192 04:18:39,720 --> 04:18:44,520 or the playground console whatever you want to call it okay 3193 04:18:44,520 --> 04:18:49,080 then we have another topic to actually discuss and this is this goes to a 3194 04:18:49,080 --> 04:18:52,439 little bit more um I would say Advanced but I think 3195 04:18:52,439 --> 04:18:58,560 generics are Advanced topics to start with so we shouldn't be scared of having 3196 04:18:58,560 --> 04:19:04,020 a look at some Advanced topics in here so let's go ahead and talk a little bit 3197 04:19:04,020 --> 04:19:10,620 about Associated types in protocols okay so and this is this makes generic 3198 04:19:10,620 --> 04:19:13,319 protocols we've already talked about protocols before but we haven't talked 3199 04:19:13,319 --> 04:19:17,580 about generic protocols so let me just show you an example and demonstrate how 3200 04:19:17,580 --> 04:19:21,660 generic protocols work in the beginning it might not make so so much sense but 3201 04:19:21,660 --> 04:19:25,800 as we go on and complete this example it will make hopefully more and more sense 3202 04:19:25,800 --> 04:19:29,880 to you okay let's create a protocol in here we call it view all right so 3203 04:19:29,880 --> 04:19:33,899 anything that can that can be displayed to the user and we call it just view all 3204 04:19:33,899 --> 04:19:38,340 right we say any view should have a function on it that is called add sub 3205 04:19:38,340 --> 04:19:43,680 View and it is basically using the same view so it says anything that's a view 3206 04:19:43,680 --> 04:19:47,580 should be able to add on another view to itself alright then we go ahead and 3207 04:19:47,580 --> 04:19:52,439 extend this view we say it we had the add sub view as a default implementation 3208 04:19:52,439 --> 04:19:57,660 in here and we say by default it is empty all right so the end the default 3209 04:19:57,660 --> 04:20:02,460 implementation of add sub U doesn't do anything then we go ahead and create a 3210 04:20:02,460 --> 04:20:06,000 structure in here we call a button and we say it conforms to the view protocol 3211 04:20:06,000 --> 04:20:11,279 and at the at the moment we say it its implementation is currently empty okay 3212 04:20:11,279 --> 04:20:15,180 if we didn't have this default implementation of the add sub view 3213 04:20:15,180 --> 04:20:20,699 function then button structure would have had to implement the add sub view 3214 04:20:20,699 --> 04:20:25,080 functioning here as you can see suggested by the playground all right 3215 04:20:25,080 --> 04:20:29,760 so let's remove these comments from here we go back to how we had it before 3216 04:20:29,760 --> 04:20:34,500 then what we're going to do in here is to create a protocol and we say and we 3217 04:20:34,500 --> 04:20:40,319 want to basically represent every object in our system that can be turned into a 3218 04:20:40,319 --> 04:20:46,439 view let's say you have a struct person okay and then you say it has a name and 3219 04:20:46,439 --> 04:20:51,060 then you want to say I want to somehow present this person on my user interface 3220 04:20:51,060 --> 04:20:55,020 and then you say okay I want to make it presentable all right so you could 3221 04:20:55,020 --> 04:20:59,040 Define anything in your system that is presentable as a View using a protocol 3222 04:20:59,040 --> 04:21:04,439 let's say protocol presentable as view all right and this is kind of like 3223 04:21:04,439 --> 04:21:09,600 hypothetical at the moment but later in this course we will actually talk about 3224 04:21:09,600 --> 04:21:16,080 mvvm in iOS or Macos and watch us using for instance combine and Swift UI plus 3225 04:21:16,080 --> 04:21:20,819 RX Swift on RX Coco but for now just this is a hypothetical protocol but it 3226 04:21:20,819 --> 04:21:24,479 is very real actually I use this in production today so 3227 04:21:24,479 --> 04:21:28,739 and I just want to give you an example of how this could look like all right 3228 04:21:28,739 --> 04:21:33,840 now if you want to turn a protocol to a generic protocol you use a syntax or a 3229 04:21:33,840 --> 04:21:38,460 keyword called Associated type and using Associated type is almost as if you say 3230 04:21:38,460 --> 04:21:42,420 presentable ads view has some sort of a generic parameter but this syntax isn't 3231 04:21:42,420 --> 04:21:45,600 accepted and so if you get an error okay you can actually see it says an 3232 04:21:45,600 --> 04:21:50,580 Associated type name V must be declared so let's go ahead and Define this we say 3233 04:21:50,580 --> 04:21:55,859 Associated type and we say view type should be any data type that conforms to 3234 04:21:55,859 --> 04:22:00,000 the view protocol you see what we did in here we didn't just leave it empty we 3235 04:22:00,000 --> 04:22:05,340 said if something is presentable as view its view should actually be be of type 3236 04:22:05,340 --> 04:22:11,699 view all right so it can either be a button or it can perhaps be struct table 3237 04:22:11,699 --> 04:22:16,560 here's a view all right and maybe this struck the person will conform to 3238 04:22:16,560 --> 04:22:20,819 presentable as view and say that my you type is actually a table all right again 3239 04:22:20,819 --> 04:22:23,640 this is hypothetical at the moment at least 3240 04:22:23,640 --> 04:22:27,180 then we say any object that is presentable as view should be able to 3241 04:22:27,180 --> 04:22:30,960 produce a view for us to display the user so we say produce view is a 3242 04:22:30,960 --> 04:22:35,340 function okay and this guy should actually produce a view of type not view 3243 04:22:35,340 --> 04:22:40,979 but view type all right so if your view type is for instance button then this 3244 04:22:40,979 --> 04:22:45,479 function should produce a button if your view type is table then this function 3245 04:22:45,479 --> 04:22:49,920 should produce a table then we can't go ahead and create the 3246 04:22:49,920 --> 04:22:53,420 next function in this protocol let's let's just call it configure so we say 3247 04:22:53,420 --> 04:22:58,560 anytime we want to present a an object as a view we can allow it to configure 3248 04:22:58,560 --> 04:23:04,380 itself using a super view as its reference so super View and we say this 3249 04:23:04,380 --> 04:23:10,739 is a view as well and we save this view is view type so we say the super view 3250 04:23:10,739 --> 04:23:16,140 could be any view but this view oops type but this view should be is of type 3251 04:23:16,140 --> 04:23:20,760 view type which is a generic parameter to this vertical okay and last but not 3252 04:23:20,760 --> 04:23:24,239 least then every object that is presentable as view should have a 3253 04:23:24,239 --> 04:23:28,199 function on it that is called present all right and in here we say view is 3254 04:23:28,199 --> 04:23:33,840 view type and then we say on super view view all right so this view we're 3255 04:23:33,840 --> 04:23:37,739 already sure it is of type view type because this configure function sorry 3256 04:23:37,739 --> 04:23:41,220 this produced view function actually produces a view type and that same view 3257 04:23:41,220 --> 04:23:45,239 will be passed to this percent function okay and a superview should be anything 3258 04:23:45,239 --> 04:23:51,000 that is a few okay so that that was the X their protocol definition itself all 3259 04:23:51,000 --> 04:23:54,660 right let's go ahead and Define implement it and basically do some 3260 04:23:54,660 --> 04:23:57,899 default implementation for some of these functions inside this protocol so we say 3261 04:23:57,899 --> 04:24:03,300 extension presentable as View and now this is a generic protocol simply 3262 04:24:03,300 --> 04:24:08,760 because it has an Associated type all right then we go ahead and configure our 3263 04:24:08,760 --> 04:24:12,479 we write our configure function in here so like that 3264 04:24:12,479 --> 04:24:16,920 let's just paste it in here and we say it's default implementation is empty by 3265 04:24:16,920 --> 04:24:22,739 default all right then we will have a we will implement the present function all 3266 04:24:22,739 --> 04:24:28,500 right like this and upon presenting a view on a super view we just go to super 3267 04:24:28,500 --> 04:24:32,819 View and we say add sub view view all right because we already know anything 3268 04:24:32,819 --> 04:24:37,560 that is a view has this add sub view function on it so we just call it all 3269 04:24:37,560 --> 04:24:42,300 right then what we can do to make this all very exciting we say we create a 3270 04:24:42,300 --> 04:24:47,520 button called my button which is presentable as a view all right then we 3271 04:24:47,520 --> 04:24:52,319 know that this function and this button has to have two function implementations 3272 04:24:52,319 --> 04:24:57,479 and they're the remaining two functions actually we don't want to do that so you 3273 04:24:57,479 --> 04:25:03,540 can see presentable as view requires four actually three functions it has a 3274 04:25:03,540 --> 04:25:08,160 produced View and it has a configure Ampersand and these two functions at the 3275 04:25:08,160 --> 04:25:13,800 moment have default implementations right here but the Purdue view function 3276 04:25:13,800 --> 04:25:18,359 doesn't have a default implementation so you can go ahead in here and say that 3277 04:25:18,359 --> 04:25:23,460 you want to Define produce View produce view okay and then we change 3278 04:25:23,460 --> 04:25:27,060 this and we say this actually returns a button as we've defined it in here 3279 04:25:27,060 --> 04:25:31,560 button is a view all right and according to our protocol implementation the 3280 04:25:31,560 --> 04:25:35,460 producer has to produce a view type that conforms to the view protocol and button 3281 04:25:35,460 --> 04:25:40,199 does that it conforms to the view protocol in here okay so inside produce 3282 04:25:40,199 --> 04:25:45,120 view we just say we return an instance up button just like that all right now 3283 04:25:45,120 --> 04:25:48,359 what's going to happen is that you don't have to implement anything else except 3284 04:25:48,359 --> 04:25:52,859 for this but if you want to go ahead and for instance do it as configure function 3285 04:25:52,859 --> 04:25:57,420 in here so as soon as you start typing it let's say configure you can see then 3286 04:25:57,420 --> 04:26:03,120 a swift understood that super view is a view however this view is a button but 3287 04:26:03,120 --> 04:26:07,380 how they didn't understand the answer button the reason is that we changed the 3288 04:26:07,380 --> 04:26:11,880 implementation of produce view so that it produces a button then Swift went to 3289 04:26:11,880 --> 04:26:15,060 this protocol implementation in here and said oh produce view is producing a 3290 04:26:15,060 --> 04:26:20,040 button so everywhere in this protocol where I see view type I'm going to 3291 04:26:20,040 --> 04:26:26,520 replace it by button so it did this pretty much button button and button you 3292 04:26:26,520 --> 04:26:31,080 can actually go ahead and test that by adding for instance also at the present 3293 04:26:31,080 --> 04:26:36,120 function in here you can say present and you can see superview the view is a 3294 04:26:36,120 --> 04:26:43,220 button so that's how generics work basically in in Swift protocols okay so 3295 04:26:43,220 --> 04:26:49,620 it's very very simple when you look at the whole thing but if you go into 3296 04:26:49,620 --> 04:26:53,279 details you can actually see there's lots of things to learn about how 3297 04:26:53,279 --> 04:26:58,319 generics work with protocols especially and Associated types so just know that 3298 04:26:58,319 --> 04:27:02,600 for now that protocols can become generics using Associated types and 3299 04:27:02,600 --> 04:27:06,899 sometimes in Swift you need to know about them and you need to use them but 3300 04:27:06,899 --> 04:27:10,859 if you're not working so much with generics you probably don't have to 3301 04:27:10,859 --> 04:27:15,359 bother so much with Associated types but again if you feel intimidated by 3302 04:27:15,359 --> 04:27:19,500 generics and Swift I think you need to tackle that fear and go ahead and 3303 04:27:19,500 --> 04:27:22,560 actually play with generics so much that you become so comfortable with them that 3304 04:27:22,560 --> 04:27:27,300 it becomes a part of your day-to-day tool and day-to-day way of working with 3305 04:27:27,300 --> 04:27:32,100 swift okay now if you want to extend generic 3306 04:27:32,100 --> 04:27:36,899 protocols just like you have extension on for instance here and you can see we 3307 04:27:36,899 --> 04:27:40,880 have extension on this generic protocol you can go ahead and actually 3308 04:27:40,880 --> 04:27:47,399 constrain your generic extensions to specific types so let's say that you say 3309 04:27:47,399 --> 04:27:54,960 extension presentable ads View and then you can say where view type view type is 3310 04:27:54,960 --> 04:27:59,939 equal to a button all right this way you're training extension on any object 3311 04:27:59,939 --> 04:28:03,840 that conforms to presentable as view as long as that object's view type is a 3312 04:28:03,840 --> 04:28:09,060 button if you did this let's see what Swift says actually so we're just 3313 04:28:09,060 --> 04:28:12,060 creating a simple extension Representatives view if you add a 3314 04:28:12,060 --> 04:28:15,420 function to this any object that conforms to presentable svu's protocol 3315 04:28:15,420 --> 04:28:20,159 is going to get your extension values and or variables and functions however 3316 04:28:20,159 --> 04:28:25,319 this way only presentable as view conforming objects that have a view type 3317 04:28:25,319 --> 04:28:29,580 of button will get your extension all right so let's say func do something 3318 04:28:29,580 --> 04:28:33,659 with button so we are adding a simple function in here and we'll say this is a 3319 04:28:33,659 --> 04:28:38,340 button all right then let's go ahead and create a button we say button is an 3320 04:28:38,340 --> 04:28:43,140 instance of my button and since my button conforms to the presentable ads 3321 04:28:43,140 --> 04:28:47,159 view protocol we can say button do something 3322 04:28:47,159 --> 04:28:53,040 with button right however if we went ahead in here and set structure table is 3323 04:28:53,040 --> 04:28:57,359 also a view actually let's go to my button and we 3324 04:28:57,359 --> 04:29:02,159 will just say my button is we copy that code and we go ahead in here and we save 3325 04:29:02,159 --> 04:29:08,399 my table okay my table and in here where we have button we create another struct 3326 04:29:08,399 --> 04:29:12,779 and we say table is a view and we say it's empty as well all right then we go 3327 04:29:12,779 --> 04:29:19,020 back in here inside our my table we say that my table produces a table and in 3328 04:29:19,020 --> 04:29:23,159 here we just create an instance of table and we change this as well to table all 3329 04:29:23,159 --> 04:29:27,840 right so and we can remove the configure function as well we don't have to have 3330 04:29:27,840 --> 04:29:33,120 it in there now if we go ahead and say my table table is an instance of my 3331 04:29:33,120 --> 04:29:38,340 table if you say my table dot you can see that you don't have access to to do 3332 04:29:38,340 --> 04:29:43,199 something with button function if you want my table to have the same extension 3333 04:29:43,199 --> 04:29:47,159 do something with button and first of all you'd have to change the name of 3334 04:29:47,159 --> 04:29:51,239 this function so you say do something with view for instance 3335 04:29:51,239 --> 04:29:55,680 with View and then you also have to remove this generic constraint from here 3336 04:29:55,680 --> 04:30:01,260 because my table doesn't produce a button it actually produces a table then 3337 04:30:01,260 --> 04:30:06,000 your table my table will have to do something with view function as well all 3338 04:30:06,000 --> 04:30:11,460 right so I hope that this makes generics a little bit more clear 3339 04:30:11,460 --> 04:30:17,699 to us at at least by this point now apart from all of this you can also 3340 04:30:17,699 --> 04:30:22,500 as I mentioned like when we saw this extension on array of strings let's see 3341 04:30:22,500 --> 04:30:27,239 where we did that longest string okay you can also create other extensions on 3342 04:30:27,239 --> 04:30:30,840 arrays even though there are generic types such as for instance calculating 3343 04:30:30,840 --> 04:30:35,120 the average value of an array of integers so you can say extension 3344 04:30:35,120 --> 04:30:40,020 int so any array and that contains integers and then you can say a function 3345 04:30:40,020 --> 04:30:43,680 that calculates the average values and we say double 3346 04:30:43,680 --> 04:30:48,960 and then we say self reduce this is a special generic function on any array 3347 04:30:48,960 --> 04:30:54,239 and you start with a seed value and in here you do your operation you basically 3348 04:30:54,239 --> 04:30:59,340 what it does is that if you have values one two three four it says okay I start 3349 04:30:59,340 --> 04:31:05,340 with the value of 0. then I go to your first element then I say 0 and 1. so 3350 04:31:05,340 --> 04:31:09,120 then we say Okay Plus them together it says okay zero and one plus together 3351 04:31:09,120 --> 04:31:13,680 will be one then I will take this one and I will go to the next element which 3352 04:31:13,680 --> 04:31:18,540 is two and I will do this operation between these two one plus two is three 3353 04:31:18,540 --> 04:31:22,920 it says okay then I have three then I go to the next element and say three plus 3354 04:31:22,920 --> 04:31:28,380 three okay six six is here and this is I go to the next element six plus four it 3355 04:31:28,380 --> 04:31:34,500 will be ten all right so this is how reduce actually works if you take the so 3356 04:31:34,500 --> 04:31:39,659 basically this com if you say lip XXX and then in here we say XXX you can see 3357 04:31:39,659 --> 04:31:45,120 it's an integer but we want to grab the average then we have to divide this with 3358 04:31:45,120 --> 04:31:50,399 uh the count of this array so self.count and we have to convert all of these to 3359 04:31:50,399 --> 04:31:55,020 doubles so that they can actually produce a double value in here okay 3360 04:31:55,020 --> 04:31:59,399 you can see now it is quite uh happy with the code that we're written and 3361 04:31:59,399 --> 04:32:04,380 then you can say one two three and four and you get its average all right and 3362 04:32:04,380 --> 04:32:09,600 you can see then the value printed to the screen right here 2.5 all right so 3363 04:32:09,600 --> 04:32:12,779 if you had an array that was just like two and two or four and four in here 3364 04:32:12,779 --> 04:32:16,979 then the average would actually be the same value as you've entered in here 2 3365 04:32:16,979 --> 04:32:23,819 and 2 will produce two and four and four will produce uh four okay so that's how 3366 04:32:23,819 --> 04:32:29,760 you can extend existing data types that are generic such as race okay I really 3367 04:32:29,760 --> 04:32:33,779 hope that all of these examples made generics make a little bit more sense to 3368 04:32:33,779 --> 04:32:38,040 you if they didn't I think it is important that you go back and practice 3369 04:32:38,040 --> 04:32:42,120 generics yourself as well because without practice generics will probably 3370 04:32:42,120 --> 04:32:46,560 never make sense good we're done with generics let's go 3371 04:32:46,560 --> 04:32:51,239 ahead to the next section which is optionals so I'm going to create a a 3372 04:32:51,239 --> 04:32:57,060 playground in here playground and we'll say blank and we say options which is 3373 04:32:57,060 --> 04:33:01,739 also a very fun topic to talk about in Swift so let's just do that 3374 04:33:01,739 --> 04:33:07,379 good and then in here we say import foundation and let's just do this so 3375 04:33:07,379 --> 04:33:12,959 that it runs automatically as well and let's get rid of our project uh Explorer 3376 04:33:12,959 --> 04:33:18,779 to the left hand side all right so optionals indicate a value that might or 3377 04:33:18,779 --> 04:33:25,379 might not be present okay so let's say that you want to take a value and 3378 04:33:25,379 --> 04:33:29,400 multiply it by two okay so let's create a function that takes a value and 3379 04:33:29,400 --> 04:33:34,920 multiplies it by two so we say flunk multiply by two in here and then we say 3380 04:33:34,920 --> 04:33:38,100 value and you can see it's an integer and it 3381 04:33:38,100 --> 04:33:41,699 returns an integer as well all right then in here you just say value 3382 04:33:41,699 --> 04:33:46,379 multiplied by two in order to turn this data to actually 3383 04:33:46,379 --> 04:33:50,100 before I say in order to let me just explain what options then would do for 3384 04:33:50,100 --> 04:33:53,219 this function and how they would make this function perhaps a little bit more 3385 04:33:53,219 --> 04:33:57,420 fun to work with if you call this function multiply by 2 you always have 3386 04:33:57,420 --> 04:34:02,039 to produce a value in here so you can't just call this function empty we're 3387 04:34:02,039 --> 04:34:05,279 thinking that it will just produce zero if you don't pass anything to it okay 3388 04:34:05,279 --> 04:34:09,840 you can see that it says okay you have to pass a value to me in here then if 3389 04:34:09,840 --> 04:34:13,141 you don't want to do that if you just want to say okay if a value isn't there 3390 04:34:13,141 --> 04:34:18,420 just assume it is zero okay what you could do is to say okay value is 3391 04:34:18,420 --> 04:34:23,160 optional so you say it shouldn't it doesn't have to be passed on here and 3392 04:34:23,160 --> 04:34:27,299 furthermore you can assign a default value to it so you say value is an 3393 04:34:27,299 --> 04:34:31,080 optional integer that by default is not present 3394 04:34:31,080 --> 04:34:36,359 then what you can do in here you say if let's value so this is the syntax of 3395 04:34:36,359 --> 04:34:40,561 unwrapping an optional so you say if the value is present then return value 3396 04:34:40,561 --> 04:34:47,100 multiplied by two otherwise return the value of zero like this all right and 3397 04:34:47,100 --> 04:34:50,400 also there are other ways of actually doing this in Swift so you can see now 3398 04:34:50,400 --> 04:34:55,439 this function works fine because it's hitting this point since a flat value 3399 04:34:55,439 --> 04:35:00,240 syntax indicated that value is indeed nil there are other ways of doing this 3400 04:35:00,240 --> 04:35:04,500 you could actually change this code to this and do it like this you could say 3401 04:35:04,500 --> 04:35:10,320 it's an integer which by default is zero then it will work exactly as it did but 3402 04:35:10,320 --> 04:35:13,799 I'm just trying to demonstrate how optionals work and how a flat works it's 3403 04:35:13,799 --> 04:35:17,100 a little bit difficult to find hypothetical examples for using 3404 04:35:17,100 --> 04:35:21,600 optionals which is a little bit a complicated topic to explain and even 3405 04:35:21,600 --> 04:35:26,279 more complicated to find very trivial trivial examples of how to use them all 3406 04:35:26,279 --> 04:35:30,480 right but let's just leave this example as it is so now you can see that you can 3407 04:35:30,480 --> 04:35:36,480 call that function with either no value values or you could say you pass the 3408 04:35:36,480 --> 04:35:40,859 value of nil and it will produce also zero or you could say you pass a value 3409 04:35:40,859 --> 04:35:46,080 of 4 or 8 or whatever you want in here and this function will still work so 3410 04:35:46,080 --> 04:35:51,000 even it works even with the value of nil I don't know why our playground isn't 3411 04:35:51,000 --> 04:35:55,859 really running yet there we go so we got our values okay 3412 04:35:55,859 --> 04:36:01,920 you can compare optionals with nil nil is a special value meaning that the 3413 04:36:01,920 --> 04:36:06,539 absence of a value basically so you could say let H is an optional integer 3414 04:36:06,539 --> 04:36:11,459 and it is equal to nil all right so it is not present basically then you could 3415 04:36:11,459 --> 04:36:18,180 say if age is not nil age is there how odd because we expected it to not be 3416 04:36:18,180 --> 04:36:25,260 there else H is now correct okay so we kind of expect this Branch to be to be 3417 04:36:25,260 --> 04:36:29,939 executed right now and you can see that it is okay so that's how you can compare 3418 04:36:29,939 --> 04:36:35,641 a value not being nil for instance okay now if you want to take an optional 3419 04:36:35,641 --> 04:36:40,260 value and check whether it actually exists or not you should use actually 3420 04:36:40,260 --> 04:36:45,779 not you don't have to use but you can use the if flat syntax so you say if let 3421 04:36:45,779 --> 04:36:51,539 H if H is present then inside this block after if let age is not optional anymore 3422 04:36:51,539 --> 04:36:59,119 so you can see it is right here okay so then you could say h is there uh how odd 3423 04:36:59,119 --> 04:37:08,279 its value its value is H all right otherwise no age is present as expected 3424 04:37:08,279 --> 04:37:13,439 because we know that age is actually nil and we should get this uh printed two 3425 04:37:13,439 --> 04:37:19,199 that counts all right now apart from if let's way of unwrapping and optional you 3426 04:37:19,199 --> 04:37:23,820 can also use another syntax which is called guard and guard does the negation 3427 04:37:23,820 --> 04:37:27,900 of age basically so let's have a look at how Guard works so let's say we create a 3428 04:37:27,900 --> 04:37:32,699 function in here we say check age all right and in here we want to read age we 3429 04:37:32,699 --> 04:37:38,039 say we want H to be there if it isn't then we're just gonna return from this 3430 04:37:38,039 --> 04:37:42,660 function within message but if it if it isn't there we return with a message but 3431 04:37:42,660 --> 04:37:46,439 if it is there then we print something to the console for instance so you could 3432 04:37:46,439 --> 04:37:54,119 say if age is nil then you could say age is nil as expected all right 3433 04:37:54,119 --> 04:37:59,820 however there is another way of writing this function and the way to do that is 3434 04:37:59,820 --> 04:38:04,439 you say this let's say that this entire function depends on this age variable 3435 04:38:04,439 --> 04:38:10,740 right and however if you um if you type a function if you type your code like 3436 04:38:10,740 --> 04:38:14,820 this anyone reading this code might not fully understand that this age variable 3437 04:38:14,820 --> 04:38:19,580 is very important to this function's signature or dysfunctions functionality 3438 04:38:19,580 --> 04:38:24,779 and that is why Swift has an alternative way of doing this check so if your 3439 04:38:24,779 --> 04:38:29,459 function depends on some optional values and it can't really continue without 3440 04:38:29,459 --> 04:38:34,619 those options optional values actually be being present you need to perhaps use 3441 04:38:34,619 --> 04:38:41,100 the guard mechanism so in here you say Guard age shouldn't be nil else then you 3442 04:38:41,100 --> 04:38:46,260 say age is nil as expected and then you return okay so you're basically saying 3443 04:38:46,260 --> 04:38:53,160 make sure age is a nil if it is so this else reads if it is then do this and 3444 04:38:53,160 --> 04:38:57,061 inside guard you always have to return so if you don't return you actually get 3445 04:38:57,061 --> 04:39:01,439 an error so guards have this property that they need to return and because 3446 04:39:01,439 --> 04:39:07,379 that's the whole point okay and also using guard you can unwrap values as 3447 04:39:07,379 --> 04:39:12,840 well as we'll soon see so let's put this card in here and then we say the rest is 3448 04:39:12,840 --> 04:39:19,619 age is not nil here strange because we don't expect that and then we call the 3449 04:39:19,619 --> 04:39:23,641 check H function in here so we should now hit this Branch because age is 3450 04:39:23,641 --> 04:39:28,020 indeed nil so we can't just guard that it isn't nil because it is nil and it 3451 04:39:28,020 --> 04:39:33,920 will end up being here okay Now using guard you can also unwrap 3452 04:39:33,920 --> 04:39:39,718 values because you can see in here if I say let XXX is H and in here I say XXX 3453 04:39:39,718 --> 04:39:47,640 it is still an optional all right so um even in here if I select XXX as H you 3454 04:39:47,640 --> 04:39:53,040 can see XXX is indeed optional integer however in here we said make sure that 3455 04:39:53,040 --> 04:39:59,218 it isn't it isn't nil so it shouldn't be integer so I kind of expect XXX to be an 3456 04:39:59,218 --> 04:40:03,120 integer all right but it isn't and the reason behind it is that we're not 3457 04:40:03,120 --> 04:40:09,240 actually unwrapping this age we're just making sure that it isn't nil but the 3458 04:40:09,240 --> 04:40:12,240 rest of the function doesn't understand and the way to fix that is to actually 3459 04:40:12,240 --> 04:40:18,480 use garblet so let's say let's H2 int optional and we actually set a value for 3460 04:40:18,480 --> 04:40:22,740 it we set a value on zero okay then we create another function here we say 3461 04:40:22,740 --> 04:40:27,440 check age two and in here we say guard let H2 3462 04:40:27,440 --> 04:40:34,260 otherwise so if we go in here and say let XXX in here let's do a return and we 3463 04:40:34,260 --> 04:40:40,740 say XXX is equal to Age Two you can now see XXX is an unwrapped integer it's not 3464 04:40:40,740 --> 04:40:45,240 optional anymore and that is simply because we did a guard let all right and 3465 04:40:45,240 --> 04:40:50,218 then here we say age is nil how strange and then we return and then in here we 3466 04:40:50,218 --> 04:40:56,820 say Age Two is not nil as expected uh value is equal to 3467 04:40:56,820 --> 04:41:04,320 Age Two all right so this H2 in here is not uh this Valley anymore really it is 3468 04:41:04,320 --> 04:41:09,180 unwrapped within this function all right then we can call this function as normal 3469 04:41:09,180 --> 04:41:14,940 we say check H2 check H2 and we should then hit this line in here and you can 3470 04:41:14,940 --> 04:41:19,980 see the value of H is indeed printed to the console value is zero you can change 3471 04:41:19,980 --> 04:41:25,200 it to 10 if you want to and you can see that value being printed to the console 3472 04:41:25,200 --> 04:41:29,940 as well all right so that's another syntax for guard using guard let for 3473 04:41:29,940 --> 04:41:36,120 actually unwrapping an optional now optionals are actually an instance 3474 04:41:36,120 --> 04:41:41,940 of an enumeration this enumeration is called optional unsurprisingly so just 3475 04:41:41,940 --> 04:41:46,080 like you can switch on option on enumerations you can switch on options 3476 04:41:46,080 --> 04:41:51,000 so you can in here go ahead and say switch age all right and you can get 3477 04:41:51,000 --> 04:41:54,840 help from Swift to complete these for you this search statement you can go in 3478 04:41:54,840 --> 04:41:59,820 here and say fix it for me you can see this optional uh enumeration actually 3479 04:41:59,820 --> 04:42:05,878 has two cases let's see if we can find it enum optional there we go and it 3480 04:42:05,878 --> 04:42:10,798 either is the value of none meaning that it is nil or it has some value inside it 3481 04:42:10,798 --> 04:42:18,900 all right so in case of none let's just say age has no value as expected in case 3482 04:42:18,900 --> 04:42:25,320 of sum we can unwrap it and say let's say value and we say age has the value 3483 04:42:25,320 --> 04:42:31,860 of value like this and we can break in here as well break okay so age was nil 3484 04:42:31,860 --> 04:42:36,840 if you remember so we kind of expect to hit this casing here which is none and 3485 04:42:36,840 --> 04:42:42,120 it says age has no value as expected all right so that's how you would switch 3486 04:42:42,120 --> 04:42:47,820 basically on an optional value you can also go ahead and do simple comparisons 3487 04:42:47,820 --> 04:42:53,218 so if you could say if H2 for instance is equal zero so you could do that then 3488 04:42:53,218 --> 04:42:58,860 you say H2 is 0 as expected and it's not the nil and let's go to H2 and actually 3489 04:42:58,860 --> 04:43:03,180 make sure that it is zero so let's change it to zero and in here we say 3490 04:43:03,180 --> 04:43:10,860 else age to is not zero how strange all right and as 3491 04:43:10,860 --> 04:43:14,580 you can see the comparison is working so you don't so what I'm trying to say in 3492 04:43:14,580 --> 04:43:18,958 here you can actually compare an optional value with another value like 3493 04:43:18,958 --> 04:43:24,360 this without having to say if K slat or is it let case or case let I I always 3494 04:43:24,360 --> 04:43:30,840 forget that so you don't have to unwrap it using a case let's or using a switch 3495 04:43:30,840 --> 04:43:35,820 you can just compare it with an unwrap value like this as well 3496 04:43:35,820 --> 04:43:41,100 okay now you can also just like we did this comparison you can also compare 3497 04:43:41,100 --> 04:43:46,798 with the non or some cases so let's just copy and paste that code in here then we 3498 04:43:46,798 --> 04:43:52,798 say if H2 is equal to sum 0 and then you say the same code in here 3499 04:43:52,798 --> 04:43:56,218 so this these two are equal to each other I mean they're not equal but 3500 04:43:56,218 --> 04:43:59,940 they're identical to each other so it is completely up to you how you want to do 3501 04:43:59,940 --> 04:44:06,298 this code and for me if I see this code I don't assume that ah2 is optional but 3502 04:44:06,298 --> 04:44:11,040 is indeed optional and but if you write your code for me I completely understand 3503 04:44:11,040 --> 04:44:15,660 that oh H2 is optional so this is a little more descriptive of the problem 3504 04:44:15,660 --> 04:44:21,000 in hand so I actually would probably prefer this but it is up to you and your 3505 04:44:21,000 --> 04:44:27,120 team to decide on a convention on which one makes more sense to you okay now you 3506 04:44:27,120 --> 04:44:31,740 can also do optional something called optional chaining and and that means you 3507 04:44:31,740 --> 04:44:37,500 optionally access optional Properties or methods of some classes or structures so 3508 04:44:37,500 --> 04:44:40,680 let's create an example for it we say struct person 3509 04:44:40,680 --> 04:44:46,378 and we say let's name the string and we say left address is let's actually not 3510 04:44:46,378 --> 04:44:49,680 do that at the moment let's inside this structure create another structure 3511 04:44:49,680 --> 04:44:54,600 called address okay and in here we say let first line is a string and it's 3512 04:44:54,600 --> 04:44:59,218 optional all right so we if we have it at an address then this first line might 3513 04:44:59,218 --> 04:45:03,480 not be present and also uh additionally we go into person in here we say 3514 04:45:03,480 --> 04:45:08,820 addresses itself is optional so even if it is present it doesn't have to have a 3515 04:45:08,820 --> 04:45:12,840 first line but if it's not present it will be nil all right so it's like 3516 04:45:12,840 --> 04:45:17,280 optional within optional so this is optional within this optional actually 3517 04:45:17,280 --> 04:45:21,180 the other way around uh address is optional and within it there is another 3518 04:45:21,180 --> 04:45:25,378 optional property okay let's create a person in here we say Foo is a person 3519 04:45:25,378 --> 04:45:30,840 and we say it is equal to an instance of person with the name of Foo and its 3520 04:45:30,840 --> 04:45:35,760 address is nil we just say we don't have an address okay then if we say we want 3521 04:45:35,760 --> 04:45:42,240 to get this person's first line of address then we say if let Foo first 3522 04:45:42,240 --> 04:45:50,100 address line line is equal to Foo then dot address and optional optionally grab 3523 04:45:50,100 --> 04:45:54,360 the first line all right so it means address is optional we know about that 3524 04:45:54,360 --> 04:46:00,180 but go and grab its first line if it is present then we say um 3525 04:46:00,180 --> 04:46:04,378 E flat okay is equal to that 3526 04:46:04,378 --> 04:46:10,500 then we print it out through first line otherwise we say Foo doesn't have an 3527 04:46:10,500 --> 04:46:17,160 address with first line as expected so since we didn't have an 3528 04:46:17,160 --> 04:46:21,840 address for Foo at all then it shouldn't even have a first line okay so this 3529 04:46:21,840 --> 04:46:26,040 address basically Swift stops right here it says I can't go any further after 3530 04:46:26,040 --> 04:46:30,900 address because address it itself nil so I can't grab the first line of it even 3531 04:46:30,900 --> 04:46:35,458 if first line did exist the address itself doesn't exist okay so then we get 3532 04:46:35,458 --> 04:46:42,840 this message printed to the console now we can go ahead and do another like an 3533 04:46:42,840 --> 04:46:47,280 alternative way of grabbing this value is by first grabbing the address and 3534 04:46:47,280 --> 04:46:50,218 then out of the address grabbing the first line it is a little bit more code 3535 04:46:50,218 --> 04:46:55,200 and I don't actually think you win so much on it so I just wanted to show you 3536 04:46:55,200 --> 04:47:00,120 how you can do that as well let's say if let Food address is food dot address so 3537 04:47:00,120 --> 04:47:05,638 you first unwrap the address okay and then you say okay after that get the 3538 04:47:05,638 --> 04:47:09,900 first line as first line like this is equal to full address DOT first line 3539 04:47:09,900 --> 04:47:14,878 then you can say Food address and then you say first line all right but we know 3540 04:47:14,878 --> 04:47:21,000 that we don't get in here because food's address is in fact nil so we don't even 3541 04:47:21,000 --> 04:47:26,100 go inside this code in here and not in here either okay 3542 04:47:26,100 --> 04:47:30,840 now you can compare optionals using chaining as well so let's go ahead in 3543 04:47:30,840 --> 04:47:35,760 here and Define a bar person we say bar is an optional person actually and it is 3544 04:47:35,760 --> 04:47:41,878 equal to person whose name is bar and whose address is in fact an address 3545 04:47:41,878 --> 04:47:47,700 instance with the first line equal to nil all right so it has an address but 3546 04:47:47,700 --> 04:47:53,160 its first line is now then we say if bars and you see we're 3547 04:47:53,160 --> 04:47:57,000 accessing bar using an optional like a question mark simply bar simply because 3548 04:47:57,000 --> 04:48:02,638 bar in itself is an optional value if bars name is equal to bar 3549 04:48:02,638 --> 04:48:11,400 and bars address first line is equal to nil then we say bars name is bar and has 3550 04:48:11,400 --> 04:48:17,400 no first line of address okay otherwise then we can say 3551 04:48:17,400 --> 04:48:21,540 um seems like something isn't working right 3552 04:48:21,540 --> 04:48:26,218 because we know that Bar's name is indeed bar and it has an address what 3553 04:48:26,218 --> 04:48:31,740 its first line is actually nil okay but do you know this line of code actually 3554 04:48:31,740 --> 04:48:36,420 isn't saying that it has to have an address but its first line should be nil 3555 04:48:36,420 --> 04:48:41,040 it could actually work as well it will work as well if the entire dress is nil 3556 04:48:41,040 --> 04:48:44,700 so let's just change it to nil and you can see still the same code will be 3557 04:48:44,700 --> 04:48:49,440 executed all right so that's how optionality works it just continues 3558 04:48:49,440 --> 04:48:56,820 until it can't continue any further okay now you can also switch on options with 3559 04:48:56,820 --> 04:49:02,100 word Clauses all right using an optional chain so let's create a bass person in 3560 04:49:02,100 --> 04:49:04,920 here I'm just going to copy paste that code so we don't have to create many 3561 04:49:04,920 --> 04:49:09,240 persons and this time it's an optional person with an address that is present 3562 04:49:09,240 --> 04:49:13,560 and it has a first line as well all right then we can go ahead and say 3563 04:49:13,560 --> 04:49:21,420 switch on the per on baz address first line all right and in case we say in 3564 04:49:21,420 --> 04:49:29,700 case of a sum we say let at first line and we just break in here and we say 3565 04:49:29,700 --> 04:49:36,840 case and none actually let's not do that let's just say uh case first line and 3566 04:49:36,840 --> 04:49:42,180 then we can go ahead in here and add a where Clause so this is pattern matching 3567 04:49:42,180 --> 04:49:47,638 and so we're saying okay if the first line is available and using this word 3568 04:49:47,638 --> 04:49:54,480 clause is pretty much just saying and and the first line starts with uh the 3569 04:49:54,480 --> 04:50:01,378 string baths okay then we say bad's first address line is equal to 3570 04:50:01,378 --> 04:50:07,500 first line like that then we say case let's sum and then we say first line and 3571 04:50:07,500 --> 04:50:13,080 we don't have a word clause anymore and this one catches all then we say Bass 3572 04:50:13,080 --> 04:50:20,458 first address line that didn't match the previous case and 3573 04:50:20,458 --> 04:50:25,020 then we print the first line all right and then last but not least we also have 3574 04:50:25,020 --> 04:50:30,060 to cover the non case where the value the optional value is indeed nil we say 3575 04:50:30,060 --> 04:50:35,100 bass first address line is new and weird 3576 04:50:35,100 --> 04:50:38,878 okay because we already know that bass is first address line is in fact Bas 3577 04:50:38,878 --> 04:50:42,900 first line and you can see this being printed to the console it says Bas first 3578 04:50:42,900 --> 04:50:47,218 address line is bass first line as it was in here so you can have where 3579 04:50:47,218 --> 04:50:52,020 Clauses in your case statements for switching on optional 3580 04:50:52,020 --> 04:51:00,260 um enumeration or enum values okay now you also can choose to um 3581 04:51:00,260 --> 04:51:07,320 if you're using a flat or Gauntlet and you should do that uh as long as it 3582 04:51:07,320 --> 04:51:11,638 makes sense to you all right so let's create a function in here let's say we 3583 04:51:11,638 --> 04:51:16,680 say funk get full name and then we say we have first name as a string and then 3584 04:51:16,680 --> 04:51:21,360 we have a last name as an optional string and we produce an optional string 3585 04:51:21,360 --> 04:51:28,260 as well all right then we say we say that you have to have a last name 3586 04:51:28,260 --> 04:51:31,620 all right even though the function signature says optional we say that okay 3587 04:51:31,620 --> 04:51:34,620 you should have one we said if let last name 3588 04:51:34,620 --> 04:51:42,360 if we can unwrap it then we return first name and name and space then we 3589 04:51:42,360 --> 04:51:48,840 say last name all right otherwise otherwise we return nil all right now 3590 04:51:48,840 --> 04:51:53,580 that's one way of doing it so you can just in here say get full name and for 3591 04:51:53,580 --> 04:51:58,080 first name we say Foo and for last name we say nil then we call the same 3592 04:51:58,080 --> 04:52:05,458 function with uh Foo and bar as names like this so this one has a last name of 3593 04:52:05,458 --> 04:52:08,760 Nils so it should end up being here and you can see it's actually producing the 3594 04:52:08,760 --> 04:52:13,020 value of nil and this one has both first name and last name therefore it is 3595 04:52:13,020 --> 04:52:17,400 returning Foo bar as this result so that's one way of doing it but you can 3596 04:52:17,400 --> 04:52:22,620 also go ahead and use guardlet so if you copy this code from here and then we go 3597 04:52:22,620 --> 04:52:27,240 and paste it right here we say get full name two and in here you could say guard 3598 04:52:27,240 --> 04:52:31,740 let last name otherwise 3599 04:52:31,740 --> 04:52:35,520 return nil and then you switch these statements 3600 04:52:35,520 --> 04:52:40,260 basically all right so you basically the way I usually read this is like this 3601 04:52:40,260 --> 04:52:45,120 make sure last name is present otherwise return 3602 04:52:45,120 --> 04:52:51,420 and then do this otherwise basically saying if last name is present okay so 3603 04:52:51,420 --> 04:52:57,298 after doing a guard let all statements after that card let if we hit them in 3604 04:52:57,298 --> 04:53:01,020 that in those statements the value that you unwrapped in here will be present as 3605 04:53:01,020 --> 04:53:07,798 a non-optional all right so that was also short and sweet about optionals and 3606 04:53:07,798 --> 04:53:11,760 there's lots more to actually explain about options and they pop up pretty 3607 04:53:11,760 --> 04:53:16,560 much everywhere in Swift and especially Swift UI Azure as you as actually we'll 3608 04:53:16,560 --> 04:53:20,940 talk about Swift UI later in this course as well but just know that they're there 3609 04:53:20,940 --> 04:53:25,320 you need to learn them if you're working with Swift and it is very advantages if 3610 04:53:25,320 --> 04:53:30,718 you can really master optionals and suit because they're pretty much everywhere I 3611 04:53:30,718 --> 04:53:35,760 hope you enjoyed this section of the course as well and in the next core in 3612 04:53:35,760 --> 04:53:39,420 the next section we're going to talk about error handling in Swift 3613 04:53:39,420 --> 04:53:43,260 now that we've talked enough about optionals let's first do some cleanup 3614 04:53:43,260 --> 04:53:48,060 here in our workspace so I'm just going to press command command W and close all 3615 04:53:48,060 --> 04:53:52,500 these tabs that we have opening here there are quite a mini and they're not 3616 04:53:52,500 --> 04:53:57,298 really contributing to so much right now rather they're just like making our 3617 04:53:57,298 --> 04:54:01,378 workspace look a little bit dirty so I'm just gonna do command W in here and if 3618 04:54:01,378 --> 04:54:05,700 you're in Visual Studio code for instance on Linux and or even actually 3619 04:54:05,700 --> 04:54:09,958 replace build build oh okay I don't know what happened really and even if you're 3620 04:54:09,958 --> 04:54:15,420 on Linux and you're for instance having Visual Studio code open with your Swift 3621 04:54:15,420 --> 04:54:19,200 files you can also close them if you're not really interested in having them all 3622 04:54:19,200 --> 04:54:23,340 open at the same time so as mentioned we're going to go and talk about error 3623 04:54:23,340 --> 04:54:28,200 handling right now so I'm just gonna press command n and say blank in here 3624 04:54:28,200 --> 04:54:34,138 and playground and let's say error Dash handling and I'm going to create it in 3625 04:54:34,138 --> 04:54:39,900 the main workspace in here as you can see okay let's press create in here here 3626 04:54:39,900 --> 04:54:44,700 and say import foundation and like usual we're going to go in here and say that 3627 04:54:44,700 --> 04:54:50,638 it should automatically run all our code okay so error handling is one of the 3628 04:54:50,638 --> 04:54:53,520 most important Concepts in any programming language that supports 3629 04:54:53,520 --> 04:54:59,458 errors and exceptions and really the points of errors and exceptions are to 3630 04:54:59,458 --> 04:55:04,680 tell the the caller to our code or whoever is using our code that something 3631 04:55:04,680 --> 04:55:09,600 has gone wrong it's either the failure of the code that we've written such as 3632 04:55:09,600 --> 04:55:14,760 an error or it's the failure of the person calling this function or code 3633 04:55:14,760 --> 04:55:18,900 such as an exception so there is a little bit of a difference between 3634 04:55:18,900 --> 04:55:21,900 actually errors and exceptions in different programming languages but in 3635 04:55:21,900 --> 04:55:26,878 Swift usually we only talk about errors so meaning that the code found out that 3636 04:55:26,878 --> 04:55:32,100 something hasn't gone according to the plans and then it throws an error and 3637 04:55:32,100 --> 04:55:36,420 actually the word for it is actually throw in Swift indeed so there's a 3638 04:55:36,420 --> 04:55:40,138 keyword for it called Throw okay and it is the same thing in many other 3639 04:55:40,138 --> 04:55:43,920 programming languages actually it is called throw in Dart for instance as 3640 04:55:43,920 --> 04:55:46,980 well so let's have a look at an example of 3641 04:55:46,980 --> 04:55:51,718 throwing an error in Swift and catching it so we're going to create a person in 3642 04:55:51,718 --> 04:55:56,160 here let's see if I can spell struck person and let's say we have a first 3643 04:55:56,160 --> 04:56:01,620 name uh it's an optional and we say last name optional string as well okay then 3644 04:56:01,620 --> 04:56:06,900 we want to create a function in here called get full name and this function 3645 04:56:06,900 --> 04:56:12,900 should ideally return a string okay so we're going to say funk get full name 3646 04:56:12,900 --> 04:56:19,440 and we say it returns a string right however how can it return a string if 3647 04:56:19,440 --> 04:56:23,040 first name and last name are both optional meaning that they could at any 3648 04:56:23,040 --> 04:56:27,360 point both be nil or one of them could be nil and in those cases we cannot 3649 04:56:27,360 --> 04:56:31,920 produce a full name so the goal of this function is to return a string it 3650 04:56:31,920 --> 04:56:36,180 shouldn't really return an optional string because the full full name 3651 04:56:36,180 --> 04:56:39,540 shouldn't be optional then what we're going to do in here we're going to say 3652 04:56:39,540 --> 04:56:44,458 okay it is going to try to produce a string but it may actually throw so we 3653 04:56:44,458 --> 04:56:51,000 say throws okay so the function throws but inside is it will throw all right so 3654 04:56:51,000 --> 04:56:55,560 that's how the how the verb and the noun basically work 3655 04:56:55,560 --> 04:57:00,360 uh actually I think it is a noun yeah so the function is marked as thirds meaning 3656 04:57:00,360 --> 04:57:04,378 that internally it can throw an error now we're going to go ahead and Define 3657 04:57:04,378 --> 04:57:08,280 our errors inside this structure then you don't have to Define them inside the 3658 04:57:08,280 --> 04:57:12,420 structure or the class that throws them but it is usually good practice to 3659 04:57:12,420 --> 04:57:17,760 Define them within their enclosing structure or class so so to associate 3660 04:57:17,760 --> 04:57:22,980 the error objects with that structure or class okay so we're gonna go and say 3661 04:57:22,980 --> 04:57:27,240 enum errors for instance it doesn't have to be colors you could call it Myers or 3662 04:57:27,240 --> 04:57:32,340 person errors whatever okay person errors also works but in here we're just 3663 04:57:32,340 --> 04:57:36,660 going to call it errors and we need to ensure that this enum conforms to this 3664 04:57:36,660 --> 04:57:42,120 error protocol okay you can see it is a public protocol okay so you cannot throw 3665 04:57:42,120 --> 04:57:45,900 errors that are not um actually your enum if you're actually 3666 04:57:45,900 --> 04:57:51,420 going to throw its cases the entire enum needs to conform to the error protocol 3667 04:57:51,420 --> 04:57:55,260 so that's their role basically that we're going to see the first case 3668 04:57:55,260 --> 04:58:00,240 of the error is for instance first name is nil we're going to say then last name 3669 04:58:00,240 --> 04:58:03,780 is no and we're going to say case both names 3670 04:58:03,780 --> 04:58:08,218 are nil so these are the available errors that this function can throw so 3671 04:58:08,218 --> 04:58:13,620 these are the three things that can go wrong either the first name is no or the 3672 04:58:13,620 --> 04:58:18,780 last name or both in any other case means that name and last the first name 3673 04:58:18,780 --> 04:58:23,040 and last name are not nil and we can calculate the full name successfully all 3674 04:58:23,040 --> 04:58:28,920 right so as option as we've actually learned in the optionals section of this 3675 04:58:28,920 --> 04:58:35,280 video optional data type is a it is an enumeration meaning that we can do 3676 04:58:35,280 --> 04:58:40,260 switch on them so if we want to basically learn whether these two are 3677 04:58:40,260 --> 04:58:46,200 both not nil you could either do it like this a flat first name and let's last 3678 04:58:46,200 --> 04:58:51,540 name then you can produce the first name and like this first name and then last 3679 04:58:51,540 --> 04:58:56,400 name this then you should say else if first 3680 04:58:56,400 --> 04:59:01,798 name is nil and last name is not nil then you should say throw 3681 04:59:01,798 --> 04:59:06,060 and you say errors first name is nil then you have to do a 3682 04:59:06,060 --> 04:59:09,958 lot of else statements in here to understand okay first name wasn't nil 3683 04:59:09,958 --> 04:59:15,420 last name was nil and then throw uh last name is no and if both of them are 3684 04:59:15,420 --> 04:59:19,920 nailed then do this so it's a lot of if and else statements instead of all of 3685 04:59:19,920 --> 04:59:23,400 that we can just do a simple switch statement in here okay so let's just say 3686 04:59:23,400 --> 04:59:28,440 we switch and we say we switch on the first name and last name alright so this 3687 04:59:28,440 --> 04:59:33,180 is the first name we're doing is switch on two enums at the same time all right 3688 04:59:33,180 --> 04:59:38,638 so the first case and we want to handle one third both nil so we say case the 3689 04:59:38,638 --> 04:59:44,040 first one is none and the second one is none okay in this case both names are 3690 04:59:44,040 --> 04:59:49,500 nails so we say Throw errors both names are name the next case we 3691 04:59:49,500 --> 04:59:54,718 want to make sure that um we want to basically see if the first 3692 04:59:54,718 --> 05:00:00,000 name is nil but the last name is not milk so we say first name is nil and the 3693 05:00:00,000 --> 05:00:05,340 last name is not mil remember sum and non-30 cases of optional so if you go in 3694 05:00:05,340 --> 05:00:09,540 here do you remember these none and some some meaning that there is a value so 3695 05:00:09,540 --> 05:00:13,378 we're saying that there is no value for first name but there is some value for 3696 05:00:13,378 --> 05:00:18,000 last name in the case I'm not having a first name then we throw an err and we 3697 05:00:18,000 --> 05:00:22,740 say first name is no then we reverse these so we say in here 3698 05:00:22,740 --> 05:00:27,600 we take this non we say the first name is sum value but the last name is no 3699 05:00:27,600 --> 05:00:33,420 values and then we say last name is no and in the other case then we say in the 3700 05:00:33,420 --> 05:00:38,340 case of actually having a first name and last name so we say case let sum first 3701 05:00:38,340 --> 05:00:42,840 name and some last name 3702 05:00:42,840 --> 05:00:48,360 in here then we can calculate we say return and we return a string with the 3703 05:00:48,360 --> 05:00:53,820 first name and last name in here just like that okay so this is this is like 3704 05:00:53,820 --> 05:00:58,138 some sort of a pattern matching you could say in Swift and pattern matching 3705 05:00:58,138 --> 05:01:02,760 in Swift is very powerful I mean I would say it's even more powerful than pattern 3706 05:01:02,760 --> 05:01:08,100 matching for instance in Rust which is also in its in its own very powerful but 3707 05:01:08,100 --> 05:01:11,940 Swift has some really neat features when it comes to power matching with switch 3708 05:01:11,940 --> 05:01:16,200 statements for instance okay okay so let's go ahead now and create an 3709 05:01:16,200 --> 05:01:21,718 instance of this person's structure we say let's oops can I spell let's Foo and 3710 05:01:21,718 --> 05:01:24,958 we say person and for the first name we're going to 3711 05:01:24,958 --> 05:01:29,520 say Foo and for the last name we're gonna say nil all right so now we want 3712 05:01:29,520 --> 05:01:34,860 to go ahead and grab the lat the full name of this person and knowing full 3713 05:01:34,860 --> 05:01:39,718 well that the last name is no meaning that we're gonna get into this case 3714 05:01:39,718 --> 05:01:43,320 actually no sorry this case last name is no all right 3715 05:01:43,320 --> 05:01:49,440 so how do we do that because if we go ahead and say let full name is uh Foo 3716 05:01:49,440 --> 05:01:54,900 get full name get full name you can see that we're going to get an error from 3717 05:01:54,900 --> 05:01:59,218 Swift saying that actually it's very important that we see this in error it 3718 05:01:59,218 --> 05:02:03,660 says call can throw but is not marked with try it says Well it can't throw 3719 05:02:03,660 --> 05:02:07,680 basically it can throw an error but you're not trying to resolve that error 3720 05:02:07,680 --> 05:02:11,700 so the key word for trying to resolve I know or trying to actually call a 3721 05:02:11,700 --> 05:02:15,958 function for instance that can throw the keyword for it is try okay so you say 3722 05:02:15,958 --> 05:02:20,100 try however we're gonna probably get another error now and it says well it 3723 05:02:20,100 --> 05:02:24,718 crashed so the entire playground pretty much crashed and the reason is that this 3724 05:02:24,718 --> 05:02:31,020 function through but we tried this inside a inside a context that doesn't 3725 05:02:31,020 --> 05:02:35,280 have error handling so if you're using try then you need to be inside a context 3726 05:02:35,280 --> 05:02:39,540 in where in which you're handling your errors and that type of context is 3727 05:02:39,540 --> 05:02:43,798 created with the do keyword so you say do and then you place this code in here 3728 05:02:43,798 --> 05:02:49,920 okay and in here then you can go ahead and say catch and then you say got an 3729 05:02:49,920 --> 05:02:54,060 error and there is an internal error object in here which is just called 3730 05:02:54,060 --> 05:02:58,620 error okay and you can see now we are getting this in here and says God error 3731 05:02:58,620 --> 05:03:03,718 and it says last name is no so this is according to what we basically expected 3732 05:03:03,718 --> 05:03:07,860 okay so just remember do and catch and inside the cache block if you don't 3733 05:03:07,860 --> 05:03:13,320 specify anything in here and like let's e or something because then we're going 3734 05:03:13,320 --> 05:03:17,638 to get e in here if you don't specify how you want to catch in into which 3735 05:03:17,638 --> 05:03:22,138 variable there is an internal hidden variable called error inside every catch 3736 05:03:22,138 --> 05:03:26,878 statement okay good now if you also want to I mean this 3737 05:03:26,878 --> 05:03:31,200 this just catches every error any error pretty much okay so if you go in here 3738 05:03:31,200 --> 05:03:35,580 and say Foo and the first name and last name for 3739 05:03:35,580 --> 05:03:39,718 it is nil now you see you catch another error that's called both names are nil 3740 05:03:39,718 --> 05:03:43,980 okay but what if you want to catch specific figures you don't want to catch 3741 05:03:43,980 --> 05:03:47,458 every error you want to catch for instance specific errors you can you can 3742 05:03:47,458 --> 05:03:52,080 say I just want to catch person errors okay and any other error that happens in 3743 05:03:52,080 --> 05:03:56,160 here I don't want to catch it because remember inside the do statement you can 3744 05:03:56,160 --> 05:04:00,240 actually have a lot of code you can have a lot code in here and you can say let 3745 05:04:00,240 --> 05:04:05,218 blah is try something else okay and any of these statements that have tried 3746 05:04:05,218 --> 05:04:09,420 before them they can throw and they then those errors that are thrown could be of 3747 05:04:09,420 --> 05:04:13,798 different types So within the do statement you can have multiple uh lines 3748 05:04:13,798 --> 05:04:18,180 of code Each of which can also throw different types of Errors if that is the 3749 05:04:18,180 --> 05:04:23,240 case how can you catch specific errors and the way to do that is using the is 3750 05:04:23,240 --> 05:04:28,560 keyword after catch I'll show you so let's copy this in here that we have and 3751 05:04:28,560 --> 05:04:33,060 paste it and then we put the full name in here just so that we get the full 3752 05:04:33,060 --> 05:04:37,680 name printed to the screen if if any but we already know that there will be no 3753 05:04:37,680 --> 05:04:42,780 full name and in here we're going to say catch is person.heirs 3754 05:04:42,780 --> 05:04:46,920 I like this okay and you can see in here this 3755 05:04:46,920 --> 05:04:51,958 statement is still I mean let's see here okay we're gonna get rid of this one 3756 05:04:51,958 --> 05:04:56,040 because we already know that is a person error okay 3757 05:04:56,040 --> 05:05:00,060 so we have pattern matching basically on our catch and we can't actually grab the 3758 05:05:00,060 --> 05:05:04,378 variable out of it anymore so we we detected that it's a person error and 3759 05:05:04,378 --> 05:05:08,580 then the error variable isn't available to us anymore after doing this pattern 3760 05:05:08,580 --> 05:05:13,378 matching okay so this is how you would look for specific types of errors in 3761 05:05:13,378 --> 05:05:19,260 your catch statements all right now you can also catch specific errors I mean 3762 05:05:19,260 --> 05:05:24,000 here you're basically matching the error against a type but then you would be 3763 05:05:24,000 --> 05:05:29,400 asking yourself well but how do I know which one of these errors it is okay and 3764 05:05:29,400 --> 05:05:34,680 you can actually catch specific errors just by typing catch which error okay so 3765 05:05:34,680 --> 05:05:38,700 let's copy this code actually maybe let's create an another variable in here 3766 05:05:38,700 --> 05:05:44,280 we say let bar equal to person and in this case we say both first name and 3767 05:05:44,280 --> 05:05:48,780 last name are nil all right like this then we're going to copy this code that 3768 05:05:48,780 --> 05:05:52,740 we have in here and right after bar we're going to paste that and we say 3769 05:05:52,740 --> 05:05:58,138 full name is bar get full name all right and then in here inside catch we're 3770 05:05:58,138 --> 05:06:02,120 going to change this code that we have and instead we say catch person errors 3771 05:06:02,120 --> 05:06:07,138 and a first name is nil then we say first name 3772 05:06:07,138 --> 05:06:12,780 is no like that and then I copy I'll copy this and I say 3773 05:06:12,780 --> 05:06:21,180 we also want to catch last name is no and we say last name is no then we say 3774 05:06:21,180 --> 05:06:27,840 okay we also want to catch person dot errors both names are now and we say 3775 05:06:27,840 --> 05:06:33,540 both names are nil and otherwise at the end we have a catch all Block in here 3776 05:06:33,540 --> 05:06:39,120 let me say some other error was thrown okay so now this now you see you can 3777 05:06:39,120 --> 05:06:42,660 we're basically getting this error in here both names are nailed as expected 3778 05:06:42,660 --> 05:06:46,920 first name and last name or not are basically nil okay so this is how you 3779 05:06:46,920 --> 05:06:51,780 can catch specific errors as well this is how you can catch air types like 3780 05:06:51,780 --> 05:06:57,240 errors of this type but inside this we already know that we have three specific 3781 05:06:57,240 --> 05:07:01,740 errors and if you want to catch any of those specific errors you can do do just 3782 05:07:01,740 --> 05:07:08,760 catch and that that specific here okay so that's another way of handling errors 3783 05:07:08,760 --> 05:07:13,700 now we've had a look just at one function at the moment that can throw 3784 05:07:13,700 --> 05:07:20,100 but uh you can also do you can basically throw errors inside Constructors as well 3785 05:07:20,100 --> 05:07:26,520 of structures or classes meaning that you try to construct an object but the 3786 05:07:26,520 --> 05:07:30,958 parameters that you're passing to that object are somehow not valid and so as 3787 05:07:30,958 --> 05:07:35,580 you know the Constructor or initializer of classes and structures have complete 3788 05:07:35,580 --> 05:07:40,560 rights to do some validation on the data that you're passing to them if those 3789 05:07:40,560 --> 05:07:45,000 data for some reason are not correct according to the validation of that 3790 05:07:45,000 --> 05:07:49,560 structure or class then the class or structure should be able to throw okay 3791 05:07:49,560 --> 05:07:53,780 and I'll show you now how you can Define throwing 3792 05:07:53,780 --> 05:07:58,020 initializers or Constructors for structures and classes so let's create a 3793 05:07:58,020 --> 05:08:04,020 struct car in here okay and then we say let manufacturer and this manufacturer 3794 05:08:04,020 --> 05:08:09,378 is a string then what we want to do is to create a a 3795 05:08:09,378 --> 05:08:14,218 Constructor or initializer for this car that looks at the manufacturer that you 3796 05:08:14,218 --> 05:08:18,120 pass to us and if it is empty then it's going to throw an error because at the 3797 05:08:18,120 --> 05:08:22,920 moment you can say my car is a car with a manufacturer of empty string and this 3798 05:08:22,920 --> 05:08:26,878 is not valid according I mean to our rules you shouldn't have a card that 3799 05:08:26,878 --> 05:08:31,680 doesn't have a manufacturer okay so we want to basically catch this case we 3800 05:08:31,680 --> 05:08:35,520 want to see okay when you pass the manufacturer to the structure is it 3801 05:08:35,520 --> 05:08:38,638 empty if it is then we want to throw an error so let's go ahead and Define that 3802 05:08:38,638 --> 05:08:43,620 error first so we say enum errors and of course we have to conform to the error 3803 05:08:43,620 --> 05:08:48,840 protocol and we say case invalid manufacturer it is a very complicated 3804 05:08:48,840 --> 05:08:52,860 word to type in my opinion then we go ahead and we say okay we have an 3805 05:08:52,860 --> 05:08:56,400 initializer in here which takes in the manufacturer okay so I'm just going to 3806 05:08:56,400 --> 05:09:00,600 copy this so I don't have to type it anymore and then in here we say this 3807 05:09:00,600 --> 05:09:05,760 init function and it or initializer actually throws and then we say if the 3808 05:09:05,760 --> 05:09:12,298 manufacturer is empty then throw errors dot invalid manufacturer otherwise self 3809 05:09:12,298 --> 05:09:17,100 manufacture is equal to that manufacturer okay so you can see then we 3810 05:09:17,100 --> 05:09:20,700 don't have a problem in here the only problem actually we have is that we're 3811 05:09:20,700 --> 05:09:24,718 now calling this now Swift understands that this call to the initializer of car 3812 05:09:24,718 --> 05:09:30,480 is throwing but we're not trying it okay so let's go ahead and do a try on this 3813 05:09:30,480 --> 05:09:35,520 so we say do and we say we catch car errors 3814 05:09:35,520 --> 05:09:40,860 invalid manufacturer and we just have a catch Hall case in here as well so we go 3815 05:09:40,860 --> 05:09:47,160 into the do and we say try this code and in here then we say invalid manufacturer 3816 05:09:47,160 --> 05:09:53,160 and we say some other error just like this okay now you should be able to see 3817 05:09:53,160 --> 05:09:58,080 that we get this invalid manufacturer and pass in here so now the important 3818 05:09:58,080 --> 05:10:01,798 thing is also that if you're inside this do clause 3819 05:10:01,798 --> 05:10:06,420 and after this try statement you can definitely use my car so you can say my 3820 05:10:06,420 --> 05:10:09,540 car that manufacturer do whatever you want with it but you already know that 3821 05:10:09,540 --> 05:10:12,480 none of this code is going to be executed because the way we're calling 3822 05:10:12,480 --> 05:10:17,100 this car or the initializer of the car structure is that it's going to throw so 3823 05:10:17,100 --> 05:10:21,958 it's never going to reach this code in here so Swift reads this code goes and 3824 05:10:21,958 --> 05:10:26,400 calls the Constructor and it gets to this throw and just immediately jumps 3825 05:10:26,400 --> 05:10:30,840 out of this into its catch statements and says okay do I have any cash that 3826 05:10:30,840 --> 05:10:34,440 matches the error that was just thrown yes and it then comes here and it 3827 05:10:34,440 --> 05:10:39,360 doesn't even go here okay so you need to kind of follow the path of the program 3828 05:10:39,360 --> 05:10:45,420 to understand what is happening really now you sometimes may not really care 3829 05:10:45,420 --> 05:10:49,320 about the errors that are being thrown from functions or initializers for 3830 05:10:49,320 --> 05:10:54,860 instance and the way to do that is that you want to grab the value of a function 3831 05:10:54,860 --> 05:11:00,240 optionally so you say if this function is successful gets me the value for it 3832 05:11:00,240 --> 05:11:04,378 so you don't actually care about the errors okay so let's go ahead and have a 3833 05:11:04,378 --> 05:11:09,420 look at the syntax where and syntax work is using a flat okay so you said if let 3834 05:11:09,420 --> 05:11:14,760 your car is equal to try with a question mark so this is simply try with a 3835 05:11:14,760 --> 05:11:18,540 question mark simply means that you don't have to have a do and catch 3836 05:11:18,540 --> 05:11:23,280 statement it says optionally try to call this function and if it is successful 3837 05:11:23,280 --> 05:11:29,878 then give me the value back okay so we say Tesla and then we have access to we 3838 05:11:29,878 --> 05:11:34,580 say success your car is a your car like this 3839 05:11:34,580 --> 05:11:42,840 otherwise we say failed to construct and error is not accessible now so if you do 3840 05:11:42,840 --> 05:11:46,260 this statement in here so you can see we're passing Tesla actually to the 3841 05:11:46,260 --> 05:11:51,540 Constructor for our initializer for car therefore this logic is not going to be 3842 05:11:51,540 --> 05:11:58,378 called and and a proper instance of car will indeed be created meaning that we 3843 05:11:58,378 --> 05:12:03,600 will indeed come in here inside the success block all right so we optionally 3844 05:12:03,600 --> 05:12:08,520 try to call this function if it was successful if it didn't throw then we 3845 05:12:08,520 --> 05:12:13,020 come here and then we have full access to this variable all right otherwise we 3846 05:12:13,020 --> 05:12:17,458 get to this clause and as you can see I've typed in here in here we lose 3847 05:12:17,458 --> 05:12:21,240 access to the error that was actually thrown so we don't have access to the 3848 05:12:21,240 --> 05:12:25,560 error object really in here okay so that's how you can optionally try to 3849 05:12:25,560 --> 05:12:29,100 call a function that throws and grab its value 3850 05:12:29,100 --> 05:12:35,580 now you can also in some very rare cases very angrily try to unwrap a the value 3851 05:12:35,580 --> 05:12:40,680 of a function that can throw please know that in in all my years of 3852 05:12:40,680 --> 05:12:46,200 working with Swift I haven't done this I know that it is available but you you 3853 05:12:46,200 --> 05:12:49,980 and you should as a swift programmer know that it exists but you should 3854 05:12:49,980 --> 05:12:56,218 almost never ever use it but and the reason behind it is that this code as I 3855 05:12:56,218 --> 05:13:01,020 said angrily unwraps a function that can throw meaning that your program or your 3856 05:13:01,020 --> 05:13:05,718 application or your IOS app or watch OS app or Mac OS app will indeed crash 3857 05:13:05,718 --> 05:13:11,100 completely and completely close should the function that you're invoking 3858 05:13:11,100 --> 05:13:16,680 actually throw an error and the Syntax for it is not with an optional try it is 3859 05:13:16,680 --> 05:13:22,200 indeed with a a how do you call this actually exclamation mark okay so let's 3860 05:13:22,200 --> 05:13:26,100 go ahead and have a look at this we say let their car 3861 05:13:26,100 --> 05:13:31,320 is equal to try and we say car with a manufacturer of Ford and you can see now 3862 05:13:31,320 --> 05:13:37,500 this will indeed be a valid um car instance and I can say their car that 3863 05:13:37,500 --> 05:13:42,120 manufacturer nothing really happened and you think okay but why did he say that 3864 05:13:42,120 --> 05:13:45,060 you should never use the syntax and the reason is that 3865 05:13:45,060 --> 05:13:50,340 should this manufacturer be empty this whole playground will crash and it will 3866 05:13:50,340 --> 05:13:55,680 just you can see in here and encounter a crash and could not finish executing 3867 05:13:55,680 --> 05:14:00,420 this same thing will happen to your app and what whether it's a Mac OS or iOS or 3868 05:14:00,420 --> 05:14:04,500 and watch OS app your app will completely crash it won't look as pretty 3869 05:14:04,500 --> 05:14:08,700 as it did in the playground because the playground it still was open but it just 3870 05:14:08,700 --> 05:14:12,000 told you that it crashed if it is in a real application the application will 3871 05:14:12,000 --> 05:14:15,480 just completely close and the user will be baffled by what just happened so 3872 05:14:15,480 --> 05:14:19,680 please don't use the syntax try to always do I mean ideally you should do 3873 05:14:19,680 --> 05:14:26,458 do and catch if you can't do that please do try and please never try this never 3874 05:14:26,458 --> 05:14:30,840 tried this way of unwrapping values unless there is a very compelling reason 3875 05:14:30,840 --> 05:14:34,260 for it that you and your teammates for instance are completely comfortable with 3876 05:14:34,260 --> 05:14:37,740 okay now we've already looked at throwing 3877 05:14:37,740 --> 05:14:43,138 errors from functions but just know that you don't necessarily have to throw a 3878 05:14:43,138 --> 05:14:47,520 specific type of error in here we have just one enum and then here we also have 3879 05:14:47,520 --> 05:14:54,360 just one enum that Define our errors but a any function that is marked as throws 3880 05:14:54,360 --> 05:14:59,340 can't throw any error it doesn't necessarily have to throw a errors from 3881 05:14:59,340 --> 05:15:03,240 just one enumeration so let me just show you how that will look like let's create 3882 05:15:03,240 --> 05:15:06,900 a struct in here and we call it dog all right 3883 05:15:06,900 --> 05:15:11,940 like this and inside this let me actually create some empty spaces so we 3884 05:15:11,940 --> 05:15:17,878 can do this so inside the dog structure we're going to create two variables one 3885 05:15:17,878 --> 05:15:22,260 is called is injured and is sleeping okay so it is injured 3886 05:15:22,260 --> 05:15:29,458 injured Bull and uh let is sleeping in here Boolean all right and 3887 05:15:29,458 --> 05:15:34,200 then we go ahead and we want to create two functions a bark function and a run 3888 05:15:34,200 --> 05:15:42,200 function so let's say funk Funk bark and Funk and we say run now 3889 05:15:42,200 --> 05:15:48,180 inside the logic of this dog structure we're gonna say okay we're gonna bark 3890 05:15:48,180 --> 05:15:53,040 like this but we're only gonna bark if we're not sleeping 3891 05:15:53,040 --> 05:15:59,040 all right so we're saying if is sleeping like this then we want to throw on air 3892 05:15:59,040 --> 05:16:04,320 so let's go ahead and Define the error for that so we say Ena barking errors 3893 05:16:04,320 --> 05:16:10,620 and we say error and in here we say cannot bark is sleeping all right then 3894 05:16:10,620 --> 05:16:15,600 we say if you're if if you're asked to bark and you're sleeping then we say 3895 05:16:15,600 --> 05:16:22,260 Throw barking hers uh cannot bark is sleeping all right otherwise we bark and 3896 05:16:22,260 --> 05:16:24,840 then we do something similar for this actually let's see what error we're 3897 05:16:24,840 --> 05:16:29,100 getting in here throw okay because this function is not marked with throws so 3898 05:16:29,100 --> 05:16:31,620 let's just change that to throws and we're also going to change this function 3899 05:16:31,620 --> 05:16:35,100 to throws okay now we're going to go ahead and create 3900 05:16:35,100 --> 05:16:39,480 another enumeration in here and we're going to call it uh running errors I 3901 05:16:39,480 --> 05:16:48,060 think let's just say enum running errors errors error and then we say case cannot 3902 05:16:48,060 --> 05:16:52,080 run is injured and we do the same thing in here so let 3903 05:16:52,080 --> 05:16:58,020 me just copy this code and put it inside run and we say if is injured okay so we 3904 05:16:58,020 --> 05:17:03,480 cannot run if we're injured then we say running errors cannot run is injured 3905 05:17:03,480 --> 05:17:08,940 otherwise we say running or run something like that okay so I think you 3906 05:17:08,940 --> 05:17:12,840 get the point so you cannot bark if you're sleeping or actually not you and 3907 05:17:12,840 --> 05:17:18,480 not me either it's the dog so the dog cannot bark if it is sleeping and it 3908 05:17:18,480 --> 05:17:22,798 cannot run if it is injured unfortunately okay so now that we have 3909 05:17:22,798 --> 05:17:27,900 those we will also go ahead and create another function and we say funk bark 3910 05:17:27,900 --> 05:17:34,500 and run which combines those two functions then we say try bark and try 3911 05:17:34,500 --> 05:17:38,580 run now what happened in here we just said try without having it do and catch 3912 05:17:38,580 --> 05:17:43,798 what happened is that we're inside a function that can throw and if you mark 3913 05:17:43,798 --> 05:17:49,200 your function as throws you can simply just try things you don't have to wrap 3914 05:17:49,200 --> 05:17:52,860 them inside do and can what happens is that if any of these 3915 05:17:52,860 --> 05:17:57,958 functions that we have inside bar can run throws then this function itself 3916 05:17:57,958 --> 05:18:03,298 will throw so if you call this function and you call Bark then Swift goes in 3917 05:18:03,298 --> 05:18:08,700 here and it says oh is it sleeping yes then it throws this error 3918 05:18:08,700 --> 05:18:14,100 from this function and since that that function was invoked from this function 3919 05:18:14,100 --> 05:18:19,798 then it will throw the error idea essentially from this function out to 3920 05:18:19,798 --> 05:18:23,820 the caller okay so if you have a function marked that throws inside it 3921 05:18:23,820 --> 05:18:27,718 you can try statements without having to wrap them inside doing catch in some 3922 05:18:27,718 --> 05:18:31,138 rare cases you actually want to wrap them inside doing catch because perhaps 3923 05:18:31,138 --> 05:18:36,000 let's say that your back-end developers tell you that hey if someone calls this 3924 05:18:36,000 --> 05:18:40,620 function and this particular function throws an error then I want you to 3925 05:18:40,620 --> 05:18:45,360 actually send an API request to the back end to log that error because that 3926 05:18:45,360 --> 05:18:49,798 should never happen for instance okay so then you can say do okay try and then 3927 05:18:49,798 --> 05:18:53,100 you say catch and in here you'll do your API 3928 05:18:53,100 --> 05:18:58,020 okay you do your API call all right and then you can actually rethrow this error 3929 05:18:58,020 --> 05:19:02,520 as well so and we probably will talk about that soon as well 3930 05:19:02,520 --> 05:19:06,958 but just know that inside a throwing function you can try your statements 3931 05:19:06,958 --> 05:19:11,160 without having to wrap them with that within do and catch okay so let's go 3932 05:19:11,160 --> 05:19:16,020 ahead and create a little dog in here that unfortunately is both sleeping and 3933 05:19:16,020 --> 05:19:21,540 injured so we say dog it's an instance of dog which is injured and it's also 3934 05:19:21,540 --> 05:19:26,940 sleeping all right then we go ahead and we create a do and catch Block in here 3935 05:19:26,940 --> 05:19:34,138 we say do and we say catch dog barking errors cannot bark and also we want to 3936 05:19:34,138 --> 05:19:38,100 catch dog sleeping errors actually what did we 3937 05:19:38,100 --> 05:19:42,060 have running here sorry running errors and cannot run is injured okay so you 3938 05:19:42,060 --> 05:19:45,360 can see how we're catching both of these errors at the same time just using a 3939 05:19:45,360 --> 05:19:52,138 comma and we'll also have a catch all in here so we say cannot uh bark is 3940 05:19:52,138 --> 05:20:00,360 sleeping or cannot run is injured all right and in cash we say 3941 05:20:00,360 --> 05:20:04,860 some other error and inside do we're going to say try dog 3942 05:20:04,860 --> 05:20:10,020 dot bark and run all right so you can see now when we do 3943 05:20:10,020 --> 05:20:14,520 that we say we get this catch statement here that says cannot bark is sleeping 3944 05:20:14,520 --> 05:20:18,660 or cannot run is injured because we've basically caught both of these Earths in 3945 05:20:18,660 --> 05:20:21,780 the same Clause all right you can separate them if you want to just using 3946 05:20:21,780 --> 05:20:26,580 separate try statements now if you go and change these to false you will see 3947 05:20:26,580 --> 05:20:30,120 that none of those errors will be thrown meaning that we will just not see 3948 05:20:30,120 --> 05:20:34,680 anything in here basically so we can say dog just to confirm that this try 3949 05:20:34,680 --> 05:20:39,840 statement actually ran its course and went to the next Lifeline 115 here okay 3950 05:20:39,840 --> 05:20:44,340 let's revert them back in here so we have this example as well 3951 05:20:44,340 --> 05:20:49,740 now now in case you're catching errors in 3952 05:20:49,740 --> 05:20:55,138 separate catch statements just know that only the first Throne error will be 3953 05:20:55,138 --> 05:21:01,200 caught all right so in here we caught both of them but again Swift called this 3954 05:21:01,200 --> 05:21:05,340 block not because both these errors happened but it called this block 3955 05:21:05,340 --> 05:21:10,200 because one at least one of these happened because remember when a 3956 05:21:10,200 --> 05:21:14,820 function throws the execution of that function completely stops so barking 3957 05:21:14,820 --> 05:21:20,340 throws an error Swift doesn't even go to running meaning that this uh this error 3958 05:21:20,340 --> 05:21:24,780 will never be thrown therefore only the bark a function will throw its error 3959 05:21:24,780 --> 05:21:29,040 which is right here Swift just completely stops the execution of this 3960 05:21:29,040 --> 05:21:33,958 function and will run I will basically run its course out of it a step out of 3961 05:21:33,958 --> 05:21:37,680 that function this error will be thrown and then we will come in here okay and 3962 05:21:37,680 --> 05:21:42,000 we can actually test that let's copy this code and paste it in here 3963 05:21:42,000 --> 05:21:46,560 and then we're going to go ahead and separate these catch statements and we 3964 05:21:46,560 --> 05:21:51,540 go in here and we say catch first cannot bark is sleeping and when you say cannot 3965 05:21:51,540 --> 05:21:56,520 bark as a sleeping then we will say catch dog dot uh 3966 05:21:56,520 --> 05:22:01,520 running errors cannot run is injured and we say 3967 05:22:01,520 --> 05:22:07,080 cannot run as injured like this and you'll see now only at the first 3968 05:22:07,080 --> 05:22:11,878 error that was thrown will be caught which is cannot bark as a sleeping even 3969 05:22:11,878 --> 05:22:18,360 though and this dog is both injured and is sleeping but the Run function will 3970 05:22:18,360 --> 05:22:23,280 never be caught inside the bark and run function simply because bark through an 3971 05:22:23,280 --> 05:22:29,760 error breaking the entire function call basically in here okay so that's how you 3972 05:22:29,760 --> 05:22:35,580 can actually understand how you can catch verse and I hope now you know 3973 05:22:35,580 --> 05:22:39,298 basically the flow of when errors are caught and that you shouldn't really 3974 05:22:39,298 --> 05:22:43,560 expect to be able to catch multiple errors at the in the same do statement 3975 05:22:43,560 --> 05:22:47,160 basically all right now let's talk about rethrows I said 3976 05:22:47,160 --> 05:22:51,000 that we're probably going to talk about rethrows but I think it is time and now 3977 05:22:51,000 --> 05:22:55,620 to talk about it so when we talk about rethrows we're talking about a function 3978 05:22:55,620 --> 05:23:01,980 that internally calls another function which can also throw so let me just 3979 05:23:01,980 --> 05:23:06,480 share an example let's create a function here called full name okay and we take 3980 05:23:06,480 --> 05:23:10,920 in a first name which is an optional string and then we say a last name which 3981 05:23:10,920 --> 05:23:15,840 is also an optional string and we say okay we ourselves cannot calculate the 3982 05:23:15,840 --> 05:23:19,500 the full name we actually need a function that can't do that for us 3983 05:23:19,500 --> 05:23:23,760 inside this function so this poor little function can't really do anything it 3984 05:23:23,760 --> 05:23:27,480 just takes the first name and last name and calculates the full name now this ER 3985 05:23:27,480 --> 05:23:32,400 is really stupid and I mean it is really not how you probably want to do your uh 3986 05:23:32,400 --> 05:23:37,080 write your sift code but it is just here for the purpose of demonstration because 3987 05:23:37,080 --> 05:23:41,700 if we didn't do a simple function like this and which looks dumb it would have 3988 05:23:41,700 --> 05:23:45,000 to go ahead and create a very complicated function which indeed is 3989 05:23:45,000 --> 05:23:49,560 production ready and you would probably use it in production code but this is a 3990 05:23:49,560 --> 05:23:55,440 little bit easier at least to get into what rethrows keyword means in Swift so 3991 05:23:55,440 --> 05:24:00,360 please just bear bear with me so we say we have a function that actually does 3992 05:24:00,360 --> 05:24:05,280 the calculation we call it calculator it takes in a string and it takes two 3993 05:24:05,280 --> 05:24:10,680 string optional parameters and it is a throwing function so we say it actually 3994 05:24:10,680 --> 05:24:16,980 throws and it returns a string in return okay and then we just do this then we 3995 05:24:16,980 --> 05:24:20,040 create our own function body in here so all these errors are going to go away 3996 05:24:20,040 --> 05:24:26,340 now since this function is going to call this function it has to do a try right 3997 05:24:26,340 --> 05:24:31,200 because this function throws therefore this function should also throw so then 3998 05:24:31,200 --> 05:24:35,340 we say throws all right and also produces an optional 3999 05:24:35,340 --> 05:24:41,040 string then okay we say try calculator and in here we have to pass the first 4000 05:24:41,040 --> 05:24:45,718 name and last name so we say first name and last name all right so if you look 4001 05:24:45,718 --> 05:24:50,520 at this code you will now see okay we're trying something in here okay and our 4002 05:24:50,520 --> 05:24:55,080 function is called uh it's marked as a throws anyone looking at this function 4003 05:24:55,080 --> 05:25:00,240 will think that somewhere inside this function we're probably throwing a 4004 05:25:00,240 --> 05:25:05,760 specific error like we're actually um have some errors that we know what 4005 05:25:05,760 --> 05:25:10,440 they are and we're throwing them perhaps okay however there is another syntax for 4006 05:25:10,440 --> 05:25:17,340 this and it is called rethrows and how this really works is that it this tells 4007 05:25:17,340 --> 05:25:22,020 Swift that this function in itself doesn't throw anything it is gonna 4008 05:25:22,020 --> 05:25:27,480 basically invoke some other functions that throw all right so we could have 4009 05:25:27,480 --> 05:25:33,660 gone in here inside the bark and run function and say this rethrows okay and 4010 05:25:33,660 --> 05:25:37,860 you can see that our code will let's actually see what happened must take a 4011 05:25:37,860 --> 05:25:40,980 throwing function argument and this is is really good we're seeing this I mean 4012 05:25:40,980 --> 05:25:46,620 this is a example and why we actually didn't mark this as free throws so in 4013 05:25:46,620 --> 05:25:50,878 order I mean the error is a little bit cryptic but what it is telling us really 4014 05:25:50,878 --> 05:25:56,700 is that if for a function to be able to be marked as a rethrows it has to it has 4015 05:25:56,700 --> 05:26:02,400 to have an argument that is a closure which throws and it should call that 4016 05:26:02,400 --> 05:26:07,798 argument and since this bar can run function it doesn't have any argument 4017 05:26:07,798 --> 05:26:12,060 that is a closure it doesn't even have any arguments that it cannot be marked 4018 05:26:12,060 --> 05:26:16,378 as rethrows okay and that's what that error was telling us however this new 4019 05:26:16,378 --> 05:26:20,400 function that we have in here has an argument that throws and we're actually 4020 05:26:20,400 --> 05:26:25,740 calling it using try and therefore we can Mark our function as rethrows and 4021 05:26:25,740 --> 05:26:29,940 this tells Swift that this function in itself is just calling an argument which 4022 05:26:29,940 --> 05:26:35,100 is a closure which in itself throws on her okay so it's just a way of telling 4023 05:26:35,100 --> 05:26:40,200 Swift that hey we have a throwing function in here and we're calling it 4024 05:26:40,200 --> 05:26:44,760 and just we re-throw the errors that this function might eventually produce 4025 05:26:44,760 --> 05:26:50,638 okay so let's then go ahead and create an enum in here and then we say enum 4026 05:26:50,638 --> 05:26:57,000 oops enum and name errors and it's a it conforms to the error 4027 05:26:57,000 --> 05:26:59,700 protocol in here and we say case first name 4028 05:26:59,700 --> 05:27:07,378 is invalid and case last name is invalid all right then we create a 4029 05:27:07,378 --> 05:27:12,240 function that can produce a a full name based on a first name and last name so 4030 05:27:12,240 --> 05:27:17,000 we say func Plus it's an operator then we say first name 4031 05:27:17,000 --> 05:27:22,260 is optional string in here then we say last name as well as an optional string 4032 05:27:22,260 --> 05:27:29,280 and we produce a an optional string in return okay like this and we also can 4033 05:27:29,280 --> 05:27:33,840 throw all right good and you can see we created this 4034 05:27:33,840 --> 05:27:37,378 function with first name optional last name optional and result optional as 4035 05:27:37,378 --> 05:27:41,878 well and throws and this function signature matches this you see optional 4036 05:27:41,878 --> 05:27:45,600 string optional string throws at returns an optional string and the reason we 4037 05:27:45,600 --> 05:27:49,680 created this function is simply because we want to call this function and 4038 05:27:49,680 --> 05:27:53,160 instead of the calculator we're going to pass a reference to this plus operator 4039 05:27:53,160 --> 05:27:58,620 in here okay so let's say we want to ensure that both 4040 05:27:58,620 --> 05:28:04,980 um both the first name and last name are presented so we say guardlet 4041 05:28:04,980 --> 05:28:10,798 first name so we ensure that first name is available and we say in case the 4042 05:28:10,798 --> 05:28:13,920 first name is 4043 05:28:13,920 --> 05:28:19,080 empty okay so the way you should read the statement 4044 05:28:19,080 --> 05:28:23,638 is that we say make sure first name is available and make sure first name is 4045 05:28:23,638 --> 05:28:28,260 not empty otherwise this is how I usually read my card statements okay 4046 05:28:28,260 --> 05:28:33,240 make sure something and something otherwise which is the sales do this 4047 05:28:33,240 --> 05:28:39,660 throw name errors first name is invalid alright so if first name is nil or that 4048 05:28:39,660 --> 05:28:43,920 it is empty then we throw this error then we're going to do something similar 4049 05:28:43,920 --> 05:28:49,798 like this then we say guard let last name ensure last name is present and 4050 05:28:49,798 --> 05:28:55,020 that it is not empty otherwise say last name is invalid so you throw that error 4051 05:28:55,020 --> 05:29:01,740 and if everything then goes fine then we say return and that first name and last 4052 05:29:01,740 --> 05:29:06,180 name and you see these variables in here are not optional anymore and that is 4053 05:29:06,180 --> 05:29:12,480 simply because we're doing a card let okay after gartlett is executed I mean 4054 05:29:12,480 --> 05:29:17,040 if last name is nil then you never get here and that's why Swift knows that if 4055 05:29:17,040 --> 05:29:20,878 you did get here and it means that you've already checked that last name 4056 05:29:20,878 --> 05:29:24,840 was not nil therefore the data type for last name is not an optional string 4057 05:29:24,840 --> 05:29:29,458 anymore it is actually a string same thing with first name it is string and 4058 05:29:29,458 --> 05:29:33,420 not an optional string okay now that we have those we can go ahead 4059 05:29:33,420 --> 05:29:38,940 and try to invoke this function right here which is full name so we go ahead 4060 05:29:38,940 --> 05:29:45,840 and say we create a do Block in here and we say let Foo bar is try get the full 4061 05:29:45,840 --> 05:29:50,280 name and we say first name let's say first 4062 05:29:50,280 --> 05:29:55,200 name we say nil last name is nil and for the calculator we pass a reference to 4063 05:29:55,200 --> 05:30:00,060 our plus operator in here okay and then we say we have to catch some errors in 4064 05:30:00,060 --> 05:30:05,218 here so let's say catch and we say name errors first name is invalid then we say 4065 05:30:05,218 --> 05:30:10,378 first name is invalid then we say cash also namers last name 4066 05:30:10,378 --> 05:30:16,740 is invalid last name is invalid like that and then we will also have a 4067 05:30:16,740 --> 05:30:22,680 catch-all block in here we say catch let err for instance and we say some other 4068 05:30:22,680 --> 05:30:28,080 error and that is equal to err okay and you can also put parenthesis around this 4069 05:30:28,080 --> 05:30:30,840 as well but this this is completely optional I think actually this is a 4070 05:30:30,840 --> 05:30:34,740 little bit cleaner to read so now you can see that we're getting first name is 4071 05:30:34,740 --> 05:30:39,718 invalid thrown in here okay and that is simply because our code just came in 4072 05:30:39,718 --> 05:30:44,400 here I was like can I unwrap first name is there a value in it nope then it 4073 05:30:44,400 --> 05:30:48,060 throws this error so it doesn't even go here and it doesn't it definitely 4074 05:30:48,060 --> 05:30:52,860 doesn't go in these cases either okay so let's change this let's change the first 4075 05:30:52,860 --> 05:30:57,000 name to Foo and you will see that your error will be the other one which is 4076 05:30:57,000 --> 05:31:01,740 last name is invalid and then you say last name is bar then all of a sudden 4077 05:31:01,740 --> 05:31:06,540 your function is gonna produce Foo bar for you okay so let's let's go ahead and 4078 05:31:06,540 --> 05:31:12,298 do one more test and in here you can see that our function which is this operator 4079 05:31:12,298 --> 05:31:17,760 is marked as throws but it is still returning an optional string however 4080 05:31:17,760 --> 05:31:22,620 internally it never returns nil it either throws which is caught by this 4081 05:31:22,620 --> 05:31:26,718 guy or not caught by it is covered by the sky 4082 05:31:26,718 --> 05:31:31,740 or it actually returns a valid string so why is it marked with returning an 4083 05:31:31,740 --> 05:31:35,458 optional string and this is actually a really good good 4084 05:31:35,458 --> 05:31:39,180 question it doesn't necessarily have to be an optional string it is better that 4085 05:31:39,180 --> 05:31:46,138 it is not and it still matches inside this function signature so because this 4086 05:31:46,138 --> 05:31:50,700 is a promotion the a strain is not optional is a promotion of an optional 4087 05:31:50,700 --> 05:31:55,080 string so it can always match it but if the emotion will never match inside a 4088 05:31:55,080 --> 05:32:00,840 function signature okay so you can if if this requires a string you can never use 4089 05:32:00,840 --> 05:32:05,400 a function that returns an optional string you will actually get an error 4090 05:32:05,400 --> 05:32:09,660 now or we should get an error there we go okay so just remember a promotion 4091 05:32:09,660 --> 05:32:13,980 will work but a demotion won't and this is a promotion we're saying that 4092 05:32:13,980 --> 05:32:17,820 although you need an optional string which is at a lower level meaning that 4093 05:32:17,820 --> 05:32:21,718 it can be nil but we will always produce a string which is at a higher level 4094 05:32:21,718 --> 05:32:25,620 meaning it's never optional so it is a promotion a promotion function 4095 05:32:25,620 --> 05:32:31,260 signatures in Swift always works okay good we've now talk about that now let's 4096 05:32:31,260 --> 05:32:35,660 also talk about results and results are also very important to understand 4097 05:32:35,660 --> 05:32:41,580 they're kind of related to error handling so that's why I wanted to name 4098 05:32:41,580 --> 05:32:46,980 them and they're usually useful when you're writing API calls okay so what we 4099 05:32:46,980 --> 05:32:51,480 want to achieve in here is to create a function that is called get previous 4100 05:32:51,480 --> 05:32:57,000 positive integer and you will pass an integer to this function and the res and 4101 05:32:57,000 --> 05:33:01,500 the responsibility of this function we're going to develop is to find the 4102 05:33:01,500 --> 05:33:05,458 positive integer right before the integer that you pass to it as an 4103 05:33:05,458 --> 05:33:09,298 argument so if you pass two this function is going to have to return the 4104 05:33:09,298 --> 05:33:13,860 value of one if you pass one this function has to return zero but what 4105 05:33:13,860 --> 05:33:18,958 happens if you pass zero there is no more positive integer before zero 4106 05:33:18,958 --> 05:33:23,700 because the next number if you do a minus one to Z basically say zero minus 4107 05:33:23,700 --> 05:33:27,060 one you are going to end up with minus one and that's not a positive integer so 4108 05:33:27,060 --> 05:33:31,320 you could say well let's just throw an error and you'd be right you could just 4109 05:33:31,320 --> 05:33:35,040 Mark your function as throws but there is another way of doing that there is 4110 05:33:35,040 --> 05:33:39,298 another way of saying that a function fails but it fails perhaps a little bit 4111 05:33:39,298 --> 05:33:44,400 more gracefully it doesn't actually throw an error but it carries an error 4112 05:33:44,400 --> 05:33:47,878 with it okay and this concept is also available in many other programming 4113 05:33:47,878 --> 05:33:51,718 languages you have it in Dart you have it in Python you have it in Rust so many 4114 05:33:51,718 --> 05:33:55,500 other programming languages have this concept and in some languages it is 4115 05:33:55,500 --> 05:34:02,040 called either but in Rust sorry in Swift it is called results so let's first go 4116 05:34:02,040 --> 05:34:06,020 ahead and Define our error so we say enum integer 4117 05:34:06,020 --> 05:34:12,660 integer errors it is an error and then we say case no positive integer before 4118 05:34:12,660 --> 05:34:18,120 this value okay enum error case did I do something 4119 05:34:18,120 --> 05:34:21,840 incorrectly in here it doesn't look like it formatted it right but this is fine 4120 05:34:21,840 --> 05:34:27,840 okay then we create our function we say func and we say get previous V is 4121 05:34:27,840 --> 05:34:36,298 positive integer and we say from int all right and in here what we need to do we 4122 05:34:36,298 --> 05:34:38,940 are not going to say that this function throws but instead we're going to say 4123 05:34:38,940 --> 05:34:44,340 that this returns a result that is either an integer or an integer error 4124 05:34:44,340 --> 05:34:49,620 like in here okay so now all of a sudden instead of this function just saying I 4125 05:34:49,620 --> 05:34:55,560 throw anything you're saying it either gives you the result or it gives you an 4126 05:34:55,560 --> 05:34:59,280 error of this specific type which is a little bit cleaner to be honest with you 4127 05:34:59,280 --> 05:35:03,120 because a throwing function doesn't necessarily specify or it can't really 4128 05:35:03,120 --> 05:35:07,680 specify the type of errors that it throws so the color the call side to 4129 05:35:07,680 --> 05:35:11,218 that function always has to have a catch-all block in order to understand 4130 05:35:11,218 --> 05:35:15,660 okay what error is actually being thrown by this function but by using a result 4131 05:35:15,660 --> 05:35:20,700 you specifically say which Earth you're gonna throw not really throw but which 4132 05:35:20,700 --> 05:35:24,060 Earth you're going to carry with you if any all right 4133 05:35:24,060 --> 05:35:30,540 so let's guard that this integer is more than zero otherwise we say return a 4134 05:35:30,540 --> 05:35:38,100 result that is a failure and its failure is indeed an integer error you can see 4135 05:35:38,100 --> 05:35:42,718 in here that is no positive integer before this value and the value is this 4136 05:35:42,718 --> 05:35:47,700 integer right here okay so regarding that the ins is more than 4137 05:35:47,700 --> 05:35:52,500 uh zero basically because otherwise we can't minus one all right then after 4138 05:35:52,500 --> 05:35:58,138 this we say okay in that case we wanna in any other case where the integer is 4139 05:35:58,138 --> 05:36:01,680 more than zero then we have to return a successful result and we say return a 4140 05:36:01,680 --> 05:36:06,360 result with success and the value is integer minus one 4141 05:36:06,360 --> 05:36:11,520 all right so you see how this function is structured at the moment okay then we 4142 05:36:11,520 --> 05:36:16,440 go ahead and create a create another function which internally calls this 4143 05:36:16,440 --> 05:36:21,240 function so we call it funk perform get and this 4144 05:36:21,240 --> 05:36:25,138 is just to add another layer of complexity really to our code so that we 4145 05:36:25,138 --> 05:36:28,440 don't go ahead and directly call this function I just want to show you how you 4146 05:36:28,440 --> 05:36:32,280 can call this function within another function okay so we say perform a get 4147 05:36:32,280 --> 05:36:37,320 for a value and we say value as an INT and inside this function we're going to 4148 05:36:37,320 --> 05:36:42,000 call the other one get previous value sorry get previous positive integer from 4149 05:36:42,000 --> 05:36:47,878 value and then since this guy returns a result and if you look at results you 4150 05:36:47,878 --> 05:36:52,378 can see just like optional result is an enumeration meaning that you can switch 4151 05:36:52,378 --> 05:36:59,400 on it so let's switch on this guy and we say in case if we get a success and we 4152 05:36:59,400 --> 05:37:03,958 say previous value all right uh actually success previous 4153 05:37:03,958 --> 05:37:07,200 value maybe not previous value previous 4154 05:37:07,200 --> 05:37:13,320 positive yet previous value then we say previous value is previous value but in 4155 05:37:13,320 --> 05:37:19,320 case we get an error we say case failure and we say error then you can say okay 4156 05:37:19,320 --> 05:37:25,138 but this error it is in itself an enum it is an integer errors enum we already 4157 05:37:25,138 --> 05:37:29,820 know that so since it's an enum you can have another switch within your switch 4158 05:37:29,820 --> 05:37:33,840 the first switch is switching on this result 4159 05:37:33,840 --> 05:37:38,820 and since it gets the error which is of type integer errors with it itself is an 4160 05:37:38,820 --> 05:37:43,200 enum then you can have another switch in here then you say switch error in the 4161 05:37:43,200 --> 05:37:49,138 case of no positive integer you put a let in here and you say this value 4162 05:37:49,138 --> 05:37:56,040 then they say no positive integer before this value all right 4163 05:37:56,040 --> 05:38:00,480 so now that we have this extra logic in here we can go ahead and call our 4164 05:38:00,480 --> 05:38:04,860 perform gets function so I'm just going to copy paste some code in here you can 4165 05:38:04,860 --> 05:38:09,840 see first we pass 0 to this function and let me comment this line out 4166 05:38:09,840 --> 05:38:15,718 we first we pass 0 and 0 then count so that zero comes in here and it's then 4167 05:38:15,718 --> 05:38:20,100 passed into this function then it comes in here and says make sure int is more 4168 05:38:20,100 --> 05:38:24,600 than zero oops it's not return the failure 4169 05:38:24,600 --> 05:38:29,458 and then it comes in here into failure gets the error we switch the error is it 4170 05:38:29,458 --> 05:38:34,260 no positive integer before yes it is indeed and then you get this line 4171 05:38:34,260 --> 05:38:37,620 printed to the console no positive integer before zero and that's correct 4172 05:38:37,620 --> 05:38:43,080 okay then we bring this go code back you can see now it will hit this block and 4173 05:38:43,080 --> 05:38:48,060 it says previous value is one all right because the previous value before 2 is 4174 05:38:48,060 --> 05:38:53,458 indeed one so that's short and sweet about error handling in so if you can 4175 05:38:53,458 --> 05:38:57,600 either use throwing functions and throwing Constructors for instance and 4176 05:38:57,600 --> 05:39:01,560 then do and catch and you also looked at try with a question mark which 4177 05:39:01,560 --> 05:39:06,298 optionally tries a function or try with an exclamation mark we should try to 4178 05:39:06,298 --> 05:39:10,378 always avoid actually because it can crash your application and then at the 4179 05:39:10,378 --> 05:39:15,958 end we looked at how result also works in Swift and how it it goes hand in hand 4180 05:39:15,958 --> 05:39:18,958 with error handling in Swift as well okay 4181 05:39:18,958 --> 05:39:23,580 now that we're done with error handling in Swift let's talk about Collections 4182 05:39:23,580 --> 05:39:27,540 and collections is something we've talked about up to this point a good 4183 05:39:27,540 --> 05:39:33,360 maybe five or ten times and the five to ten times I would say but we haven't 4184 05:39:33,360 --> 05:39:38,100 really gone into details about them so I'm gonna close this playground in here 4185 05:39:38,100 --> 05:39:43,860 I'm going to press command n and say blank in here and let's create a new 4186 05:39:43,860 --> 05:39:47,760 playground and we're going to call it collections all right and ensure that 4187 05:39:47,760 --> 05:39:52,740 it's created in your main workspace and then we say create 4188 05:39:52,740 --> 05:39:58,680 and just like normal we say import foundation and run this playground also 4189 05:39:58,680 --> 05:40:03,360 automatically we get rid of our Explorer here and then we can start talking about 4190 05:40:03,360 --> 05:40:08,520 collections so collections as their name indicates there are a collection of 4191 05:40:08,520 --> 05:40:13,680 stuff all right so for instance with numbers and if you're I mean not if but 4192 05:40:13,680 --> 05:40:16,378 since you're already familiar with other programming languages collections are 4193 05:40:16,378 --> 05:40:20,940 also called arrays or dictionaries or even Json objects for instance if you're 4194 05:40:20,940 --> 05:40:24,020 working with simple JavaScript you can just say 4195 05:40:24,020 --> 05:40:29,940 const something is equal to and then you add your values in here value blah okay 4196 05:40:29,940 --> 05:40:35,160 so this is a simple Json JavaScript and it's some sort of a collection and in 4197 05:40:35,160 --> 05:40:38,940 Swift you also have different types of collections one of them is an array so 4198 05:40:38,940 --> 05:40:43,440 you say let's numbers is one two three four for instance and then you can do 4199 05:40:43,440 --> 05:40:47,400 different things with this collection you can say give me the first value give 4200 05:40:47,400 --> 05:40:52,200 me the last value give me the count of objects in here or you can say numbers 4201 05:40:52,200 --> 05:40:59,040 map every element to its minus counterpart so you can see in here then 4202 05:40:59,040 --> 05:41:02,520 let me just bring this over so you can see we have one key one two three four 4203 05:41:02,520 --> 05:41:05,878 then the first element is one last one is four there are four elements total 4204 05:41:05,878 --> 05:41:11,400 and then here we mapped every element inside this numbers array to its minus 4205 05:41:11,400 --> 05:41:16,020 counterpart okay so this is an operator in here now if you have an array in 4206 05:41:16,020 --> 05:41:20,400 Swift you can also mutate it as long as it is a variable so let's say VAR 4207 05:41:20,400 --> 05:41:25,920 mutating numbers and we say 0 1 and 2 and then you can see mutating numbers 4208 05:41:25,920 --> 05:41:30,200 append the value of three and then mutating numbers 4209 05:41:30,200 --> 05:41:37,260 insert the value of -1 at the index of zero okay so index of zero is right here 4210 05:41:37,260 --> 05:41:41,280 not that the zero is actually let's let's just say four five and six instead 4211 05:41:41,280 --> 05:41:47,040 okay and then we append the value of seven and we then insert the value of 4212 05:41:47,040 --> 05:41:51,120 three at the index of zero meaning that the array was four five six but at the 4213 05:41:51,120 --> 05:41:56,040 end it will be three four five six seven you see what happened in here the index 4214 05:41:56,040 --> 05:42:00,360 of zero is right here and in the index of one is right here index of two is 4215 05:42:00,360 --> 05:42:04,920 right here because the in index is in arrays and any collection in pretty much 4216 05:42:04,920 --> 05:42:08,638 every program language that I know about they start at the index of zero they're 4217 05:42:08,638 --> 05:42:14,458 called zero based indexes okay so and apart from doing a pens and 4218 05:42:14,458 --> 05:42:18,420 inserts you can also insert a whole array inside an array so you can say 4219 05:42:18,420 --> 05:42:22,860 mutating numbers insert and then you can say insert the contents of for instance 4220 05:42:22,860 --> 05:42:29,638 one and two at the index of zero so let's see what happens in here 4221 05:42:29,638 --> 05:42:34,378 and then right it's not insert it is actually insert contents off so this API 4222 05:42:34,378 --> 05:42:38,400 calls called insert contents off and you can see the resulting array will be one 4223 05:42:38,400 --> 05:42:43,860 two three four five six and seven here okay you can enumerate over the elements 4224 05:42:43,860 --> 05:42:48,298 inside an array by just using a for statement for Value in numbers so then 4225 05:42:48,298 --> 05:42:52,920 you can say a value and print it to the console and now 4226 05:42:52,920 --> 05:42:57,900 um playgrounds have an interesting way of showing values over time since we're 4227 05:42:57,900 --> 05:43:01,920 animating over these values and there are four of them it can't print them all 4228 05:43:01,920 --> 05:43:06,600 in the same line so you have to click here I believe and it gives you like a 4229 05:43:06,600 --> 05:43:10,560 little graph and then you have to right click on it and you say value history 4230 05:43:10,560 --> 05:43:14,520 then you get the values one two three four otherwise it shows you a graph for 4231 05:43:14,520 --> 05:43:20,160 some reason okay and let's somehow remove this okay there we go so that's 4232 05:43:20,160 --> 05:43:24,660 how you would go through values inside an array okay 4233 05:43:24,660 --> 05:43:29,458 you can also enumerate through items inside an array with pattern matching 4234 05:43:29,458 --> 05:43:34,740 using the where Clause so if you want to for instance grab all the uh all the 4235 05:43:34,740 --> 05:43:38,638 even numbers inside this array so because you saw this printed one two 4236 05:43:38,638 --> 05:43:42,600 three and four and one and three are not even numbers but if you want to grab 4237 05:43:42,600 --> 05:43:47,160 only the even numbers you could say four value in numbers where 4238 05:43:47,160 --> 05:43:52,680 value and we're basically the the result of 4239 05:43:52,680 --> 05:43:57,900 dividing the value by 2 should be equal to zero okay so this is how you would do 4240 05:43:57,900 --> 05:44:01,860 your pattern matching if you say value in here we can do the same thing that we 4241 05:44:01,860 --> 05:44:06,480 did earlier and say value history and then you only get the values of 2 and 4 4242 05:44:06,480 --> 05:44:12,058 in here okay so that's how you can have a where Clause right after your four 4243 05:44:12,058 --> 05:44:16,500 statements now you can also map objects inside an 4244 05:44:16,500 --> 05:44:20,458 array and mapping is also very important because it's one of the most useful 4245 05:44:20,458 --> 05:44:24,780 functionalities of collections mapping means that you take the values inside 4246 05:44:24,780 --> 05:44:28,138 that collection and you turn them into something completely different if you 4247 05:44:28,138 --> 05:44:32,700 want to okay so let's say numbers you map them you see and it says okay I give 4248 05:44:32,700 --> 05:44:37,860 you the number so let's say value and in here you can say I return anything in 4249 05:44:37,860 --> 05:44:41,520 this case we've decided to return an integer and we say value multiplied by 4250 05:44:41,520 --> 05:44:46,980 two now you can all of a sudden see that numbers are 2 4 6 and 8 whereas they 4251 05:44:46,980 --> 05:44:52,620 were originally one two three and four so here you multiply them by by two 4252 05:44:52,620 --> 05:44:57,298 however inside map you can't return anything you can say I actually return a 4253 05:44:57,298 --> 05:45:02,940 stream okay and then you turn these into a string you can string first multiply 4254 05:45:02,940 --> 05:45:06,958 them by two but then turn them into a string now you can see there are strings 4255 05:45:06,958 --> 05:45:11,520 so map allows you to map it to anything all right and now that we're talking 4256 05:45:11,520 --> 05:45:15,958 about mapping it to anything you can you can guess that this map is indeed a 4257 05:45:15,958 --> 05:45:20,520 generic function because it allows you to change the resolved value and if you 4258 05:45:20,520 --> 05:45:24,420 look at its signature you can see it in is it indeed giving you the elements 4259 05:45:24,420 --> 05:45:28,620 inside the array but it allows you to throw to return anything and the result 4260 05:45:28,620 --> 05:45:34,920 would be the array of that anything okay so if I go and say let values you can 4261 05:45:34,920 --> 05:45:39,958 see values is an array of um not in this case but in this case values will be an 4262 05:45:39,958 --> 05:45:45,840 array of string okay like this so values is an array of string right 4263 05:45:45,840 --> 05:45:51,120 now and just a note about this at Maps don't necessarily have to be this 4264 05:45:51,120 --> 05:45:55,860 complicated I mean um to me this and actually we can recommend this syntax 4265 05:45:55,860 --> 05:45:59,820 more than I can recommend the next syntax I'm going to show you and simply 4266 05:45:59,820 --> 05:46:03,540 because the more information you give to the Swift compiler the faster your code 4267 05:46:03,540 --> 05:46:07,558 compiles in larger applications but if you have very simple applications you 4268 05:46:07,558 --> 05:46:13,080 don't have to do this much syntax work in Swift you could literally just say 4269 05:46:13,080 --> 05:46:16,860 okay first of all I don't want to give you I don't want to tell you what return 4270 05:46:16,860 --> 05:46:21,540 value I have and Swift still is happy with that you can also remove this in 4271 05:46:21,540 --> 05:46:25,860 here because Swift already knows the value is an integer okay and this works 4272 05:46:25,860 --> 05:46:29,218 as well and you can completely remove that and instead of value use dollar 4273 05:46:29,218 --> 05:46:34,920 zero and that works as well so your code could pretty much just look like this 4274 05:46:34,920 --> 05:46:40,860 but again I mean this does work but it is it has a very little information 4275 05:46:40,860 --> 05:46:46,020 about what that code is actually doing internally so so a new newbie software 4276 05:46:46,020 --> 05:46:50,040 developer may be quite confused by it and also as I said this is more 4277 05:46:50,040 --> 05:46:54,058 information to the compiler which allows it to compile your complicated codes in 4278 05:46:54,058 --> 05:46:56,400 the future a little bit faster as well okay 4279 05:46:56,400 --> 05:47:00,240 apart from mapping arrays you can also filter them meaning that you want to 4280 05:47:00,240 --> 05:47:04,260 grab specific values out of this array you could say numbers 4281 05:47:04,260 --> 05:47:10,138 then you filter and you say you get the value and you turn and return a Boolean 4282 05:47:10,138 --> 05:47:14,520 and for all the objects that have to be included in the result of this filter 4283 05:47:14,520 --> 05:47:20,160 function so you say if the value is greater than or equal to 3 then it 4284 05:47:20,160 --> 05:47:24,500 should be returned from the result and you can see the result is 3 and 4. okay 4285 05:47:24,500 --> 05:47:30,120 so that's how Filter Works you can also do compact mapping and compact mapping 4286 05:47:30,120 --> 05:47:36,000 mapping is similar to map but it returns an optional and the values that are 4287 05:47:36,000 --> 05:47:40,500 returned from this compact map which are nil will not be included in the results 4288 05:47:40,500 --> 05:47:46,200 so it's a compact map is a combination of map and filter okay so let's have a 4289 05:47:46,200 --> 05:47:50,878 look at that we say numbers compact map and we say we get the value as an 4290 05:47:50,878 --> 05:47:56,100 integer and we return a string okay an optional string remember it should be 4291 05:47:56,100 --> 05:48:00,660 optional optionality indicates a filtering so if it is nil it won't be 4292 05:48:00,660 --> 05:48:06,840 included in the resulting array then we say if Val value is divisible by 2. then 4293 05:48:06,840 --> 05:48:11,400 return the string of that value otherwise return nil so let's break it 4294 05:48:11,400 --> 05:48:15,540 down into separate lines it's a little bit more readable okay so you can now 4295 05:48:15,540 --> 05:48:20,040 see the result is at Raf strings that only includes two and four but it 4296 05:48:20,040 --> 05:48:25,200 doesn't include three and one or one and three basically okay so compact map when 4297 05:48:25,200 --> 05:48:29,520 you see it just know that is a is a combination of map and filter at the 4298 05:48:29,520 --> 05:48:33,660 same times arrays in Swift can also contain the 4299 05:48:33,660 --> 05:48:40,260 value of nil so let's say numbers uh numbers numbers two and it is an array 4300 05:48:40,260 --> 05:48:45,058 of optional integers so meaning that it can contain not just integers but also 4301 05:48:45,058 --> 05:48:50,700 nil then you can say one two and then nil four and five so this is completely 4302 05:48:50,700 --> 05:48:54,840 fine all right and then if you say numbers two dot count you will actually 4303 05:48:54,840 --> 05:48:59,160 see it is five because nil is one of the elements one 4304 05:48:59,160 --> 05:49:03,120 of the valid elements inside this array and if you want to grab all the values 4305 05:49:03,120 --> 05:49:07,740 inside this numbers array and that are not nil then you would say let's not 4306 05:49:07,740 --> 05:49:12,240 snails is equal to numbers 2 filter so you 4307 05:49:12,240 --> 05:49:16,378 basically say here's my integer and I return a Boolean for all the values that 4308 05:49:16,378 --> 05:49:22,080 are not known then you could say um let's say its value its name is value 4309 05:49:22,080 --> 05:49:28,020 then we say value shouldn't be nil like this all right and you can see the 4310 05:49:28,020 --> 05:49:33,378 result of this is just one two four five all right however however 4311 05:49:33,378 --> 05:49:39,180 this you will be like okay we've checked that the values are not nil and we place 4312 05:49:39,180 --> 05:49:43,980 them inside this array so this array should now be an array of integers but 4313 05:49:43,980 --> 05:49:48,540 that's not correct because if you look at this is is still an array of optional 4314 05:49:48,540 --> 05:49:52,558 integers so what's happening here is that though we checked for nail values 4315 05:49:52,558 --> 05:49:57,900 but we didn't tell and this so basically filter doesn't allow you to change the 4316 05:49:57,900 --> 05:50:02,878 data type all right you can see it always returns the same array of the 4317 05:50:02,878 --> 05:50:07,558 same element type so if our elements is optional integer the result of this 4318 05:50:07,558 --> 05:50:14,580 function will indeed be integers as well in order to grab the non-null or not nil 4319 05:50:14,580 --> 05:50:18,900 values out of this array and also change the data type you have to use compact 4320 05:50:18,900 --> 05:50:23,940 map all right so um so you could say in here not Nails is 4321 05:50:23,940 --> 05:50:29,040 numbers too and we say compact map and we say we take the integer 4322 05:50:29,040 --> 05:50:33,900 and which is value and we actually return an optional integer as well and 4323 05:50:33,900 --> 05:50:38,458 just return the same value all right if this value is nil it won't be included 4324 05:50:38,458 --> 05:50:44,458 in the result and also it won't basically change the data type so not 4325 05:50:44,458 --> 05:50:49,320 Nils is now not an array of optional integers okay I know it's complicated 4326 05:50:49,320 --> 05:50:54,600 and it's a lot of generic code but it really requires that you work with these 4327 05:50:54,600 --> 05:50:58,798 functions yourself to for it to basically click 4328 05:50:58,798 --> 05:51:04,798 now arrays can also include instances of the same object multiple times so if you 4329 05:51:04,798 --> 05:51:11,458 say numbers three and we say one two one two you can see that numbers three dot 4330 05:51:11,458 --> 05:51:16,740 count is indeed four so it contains four objects it doesn't check whether there 4331 05:51:16,740 --> 05:51:22,080 are unique or not okay arrays can also they don't necessarily have to include 4332 05:51:22,080 --> 05:51:27,180 home homogeneous objects so they can be heterogeneous meaning that you can have 4333 05:51:27,180 --> 05:51:31,740 integers and strings uh mixed up and Blended up in the same array so let's 4334 05:51:31,740 --> 05:51:37,558 say let's stuff one and we say it is an array of it has an integer of one then 4335 05:51:37,558 --> 05:51:43,080 it has hello then it has an integer of two and has a string up world but this 4336 05:51:43,080 --> 05:51:49,440 will give us an error or it should because it says it is not a homogeneous 4337 05:51:49,440 --> 05:51:53,218 array all right and it says it's a heterogeneous so in order to fix this 4338 05:51:53,218 --> 05:51:58,440 you can see Swift is telling you to actually add as any to the end of this 4339 05:51:58,440 --> 05:52:03,660 array and a collection literally could only be what is the same 4340 05:52:03,660 --> 05:52:09,718 as an array of any and I mean this to me looks fine 4341 05:52:09,718 --> 05:52:13,320 uh but I'm sure I'm not sure really what is the same collation level It could 4342 05:52:13,320 --> 05:52:17,878 only be inferred to any add explicit type annotation 4343 05:52:17,878 --> 05:52:22,138 um I believe we've already done that so I'm not really sure what it is 4344 05:52:22,138 --> 05:52:25,740 complaining about let's just say stuff one and see if Swift has understood what 4345 05:52:25,740 --> 05:52:30,958 this code is actually doing expected separator did I miss a 4346 05:52:30,958 --> 05:52:35,700 separator somewhere let's stuff one to me this looks fine but not sure 4347 05:52:35,700 --> 05:52:38,760 really what it is complaining about let me just bring it in here and then we say 4348 05:52:38,760 --> 05:52:43,020 hello let's put all of these in oh because I've missed a comma in here I 4349 05:52:43,020 --> 05:52:46,440 can see okay sorry about that so I've missed a 4350 05:52:46,440 --> 05:52:50,218 comment there so now you can see our array looks fine and if I say stuff one 4351 05:52:50,218 --> 05:52:55,260 count it should include the count of four in here okay there are four objects 4352 05:52:55,260 --> 05:52:59,458 so this is a trick to get your array to include heterogeneous objects as well 4353 05:52:59,458 --> 05:53:04,260 all right so um we can also go ahead and change the 4354 05:53:04,260 --> 05:53:08,760 Syntax for this so if I copy this and paste it in here and changes the stuff 4355 05:53:08,760 --> 05:53:13,980 too and then stuff to account if you don't want to have this as in here you 4356 05:53:13,980 --> 05:53:18,900 can also tell Swift that this is in fact an array of any by doing this column in 4357 05:53:18,900 --> 05:53:22,920 here just specifying the data type right there okay so that's another way of 4358 05:53:22,920 --> 05:53:27,958 actually achieving the same result now that we've talked enough about 4359 05:53:27,958 --> 05:53:33,540 arrays let's talk about uh sets a set is a special object it's a special 4360 05:53:33,540 --> 05:53:38,638 collection that only contains unique values all right and the way it 4361 05:53:38,638 --> 05:53:44,820 calculates uh uniqueness is based on hash values and equality all right and 4362 05:53:44,820 --> 05:53:48,298 this is a little bit complicated a lot of people think it's just hash value but 4363 05:53:48,298 --> 05:53:52,558 it is not it's also equality which is very important to understand and what 4364 05:53:52,558 --> 05:53:59,160 sets so let's create a set we say unique numbers and then we say it is a set of 4365 05:53:59,160 --> 05:54:04,080 the values one two one two and three all right and then we say unique numbers 4366 05:54:04,080 --> 05:54:10,320 count and then unique numbers map them to their minus values let's just see 4367 05:54:10,320 --> 05:54:14,878 what values we get in here you see after the creation of this set the set only 4368 05:54:14,878 --> 05:54:19,138 includes the values of three one and two so two things are quite interesting 4369 05:54:19,138 --> 05:54:24,360 about this is that it removed the duplicates so both twos were not 4370 05:54:24,360 --> 05:54:28,020 included only one instance was included it and the same thing with the value of 4371 05:54:28,020 --> 05:54:31,378 one only one instance was included so that's one thing that's interesting 4372 05:54:31,378 --> 05:54:34,980 about creation of this set or and one of the properties that's important about 4373 05:54:34,980 --> 05:54:39,240 sets it only includes unique numbers and the other one is that this array that we 4374 05:54:39,240 --> 05:54:42,480 just passed to it it's ordering was completely changed within the set so 4375 05:54:42,480 --> 05:54:48,480 sets in Swift cannot guarantee ordering as you pass the ordering to it so the 4376 05:54:48,480 --> 05:54:52,920 ordering could just be mishmashed and the set will order the items as it 4377 05:54:52,920 --> 05:54:56,360 pleases all right so 4378 05:54:56,360 --> 05:55:02,340 sets can also contain Nils so we can go ahead in here just like arrays so let's 4379 05:55:02,340 --> 05:55:10,860 say my numbers is a set of one two three and nil and five and then we say let's 4380 05:55:10,860 --> 05:55:16,200 not nil numbers if we want to get the not nil numbers then we say it is a set 4381 05:55:16,200 --> 05:55:23,400 of my numbers and then we compact map this guy a compact map and we grab only 4382 05:55:23,400 --> 05:55:27,180 the current value you can see in here compact mapping let's actually break it 4383 05:55:27,180 --> 05:55:32,040 down into separate lines so it is more readable like this and 4384 05:55:32,040 --> 05:55:36,298 like this all right so we're just taking the same values which are inside my 4385 05:55:36,298 --> 05:55:40,798 numbers returning returning them from compact map compact map what it does is 4386 05:55:40,798 --> 05:55:44,700 if the values are nailed it removes them from their result and you can see the 4387 05:55:44,700 --> 05:55:51,180 result of compact map inside a set it is an array of the values and that is the 4388 05:55:51,180 --> 05:55:54,660 reason we're putting it inside another set because we want the return value to 4389 05:55:54,660 --> 05:55:59,160 be a set as well all right and then we say not nil numbers 4390 05:55:59,160 --> 05:56:05,100 in here you can see in here we have five where is it uh two three nil one five 4391 05:56:05,100 --> 05:56:09,900 but in in there we have only three two one and five so nil was removed 4392 05:56:09,900 --> 05:56:13,920 essentially by calling compact map on that sets okay 4393 05:56:13,920 --> 05:56:17,458 now you can also create heterogeneous sets just like you can create 4394 05:56:17,458 --> 05:56:22,378 heterogeneous arrays so a set doesn't necessarily have to only have integers 4395 05:56:22,378 --> 05:56:28,558 for instance so the trick to do that is to create a set of a protocol called any 4396 05:56:28,558 --> 05:56:33,420 hashable all right so you say stuff three for instance and we say this is a 4397 05:56:33,420 --> 05:56:37,860 set of any hashable and you can look at the code for any hash well sorry it's 4398 05:56:37,860 --> 05:56:45,480 not a protocol it's a structure and we say it is equal to uh one two three and 4399 05:56:45,480 --> 05:56:49,740 then bounded all right then we can say stuff three count you will see that 4400 05:56:49,740 --> 05:56:54,780 includes four values all right so this is the trick to create a 4401 05:56:54,780 --> 05:57:00,480 heterogeneous sets as well now if you want to extract specific 4402 05:57:00,480 --> 05:57:09,240 items uh like of specific types out of uh any of these sets or arrays and let's 4403 05:57:09,240 --> 05:57:12,240 just focus on the sets right now actually let's have a look at our stuff 4404 05:57:12,240 --> 05:57:17,400 one you can see our stuff one is an array at the moment and that is an array 4405 05:57:17,400 --> 05:57:22,138 of any but if you want to grab specific objects out of this array which are of 4406 05:57:22,138 --> 05:57:27,360 specific types for instance only the strings or only the integers you can use 4407 05:57:27,360 --> 05:57:34,620 a keyword which is called as so let's say let's ins in stuff one and again 4408 05:57:34,620 --> 05:57:39,780 remember stuff one is this array it has integers and strings and you only want 4409 05:57:39,780 --> 05:57:45,120 to grab the integers out of them so then you could say ins in stuff one is stuff 4410 05:57:45,120 --> 05:57:50,280 one and then you compact map all right remember compact map does map and filter 4411 05:57:50,280 --> 05:57:55,320 at the same time then you get your value which is any and you want to optionally 4412 05:57:55,320 --> 05:58:01,740 return an integer then you say value as ins so you compare the values type to 4413 05:58:01,740 --> 05:58:06,480 an integer and optionally return it if it is integer okay 4414 05:58:06,480 --> 05:58:12,058 and then you can see in here that the result of this is only your integers 4415 05:58:12,058 --> 05:58:16,798 and you can do the same thing with strings so you can say okay let's copy 4416 05:58:16,798 --> 05:58:21,480 this and then we say strings in stuff one and then you get the value and you 4417 05:58:21,480 --> 05:58:25,500 optionally return a string and then you say as long as the data type is a string 4418 05:58:25,500 --> 05:58:31,138 I return it okay then you get the hello world printed in here okay 4419 05:58:31,138 --> 05:58:35,940 so if you if you are comfortable doing this with a race then you're probably 4420 05:58:35,940 --> 05:58:40,558 also comfortable doing that with sets and it is very similar it's actually 4421 05:58:40,558 --> 05:58:46,680 compact map on sets as well so let's copy this code ins in stuff one and then 4422 05:58:46,680 --> 05:58:52,440 we say ins in stuff three and remember stuff three is a set then we go in here 4423 05:58:52,440 --> 05:58:57,680 and we say stuff three and we compact map and the value is any hashable 4424 05:58:57,680 --> 05:59:03,000 hashable and then we optionally return an INT and then we get the result 4425 05:59:03,000 --> 05:59:07,680 printed to the screen which is two three one and you can see one two three van 4426 05:59:07,680 --> 05:59:11,878 dot so van dot was essentially removed from this set but one thing to note 4427 05:59:11,878 --> 05:59:17,160 about this is that as I mentioned before compact mapping on a set doesn't return 4428 05:59:17,160 --> 05:59:25,138 a set it actually returns an array so if you go in here and call type of which is 4429 05:59:25,138 --> 05:59:28,798 an internal function in Swift and say give me the type of ins in stuff three 4430 05:59:28,798 --> 05:59:34,500 it will tell you that this hopefully is did it crash it will tell you it's an 4431 05:59:34,500 --> 05:59:40,920 array it's not a set anymore though stuff 3 was a set uh you can see in here 4432 05:59:40,920 --> 05:59:46,378 is a set but the result of compact mapping is set is an array okay so just 4433 05:59:46,378 --> 05:59:50,878 keep that in mind now now that we talked about sets a 4434 05:59:50,878 --> 05:59:54,780 little bit and we talked about that they can contain the only that they only 4435 05:59:54,780 --> 05:59:59,520 contain uh unique objects then the question is how does it calculate 4436 05:59:59,520 --> 06:00:05,400 uniqueness and and the way it does it is using a protocol called hashable 4437 06:00:05,400 --> 06:00:10,020 now hashable a lot of people think that only thing it does it it contains a some 4438 06:00:10,020 --> 06:00:14,700 sort of a hash value is some sort of an integer value that uniquely identifies 4439 06:00:14,700 --> 06:00:18,240 every object but it but hashable protocol 4440 06:00:18,240 --> 06:00:24,298 in itself also includes equality all right so uh without without actually me 4441 06:00:24,298 --> 06:00:28,200 talking too much about that let's have a look at an example so let's just say we 4442 06:00:28,200 --> 06:00:33,600 create a person struct in here struck person and then we say we have an 4443 06:00:33,600 --> 06:00:38,458 ID so every person has an identifier we have a name of string and then we have 4444 06:00:38,458 --> 06:00:43,740 an H of integer as well okay and then we want this person to be 4445 06:00:43,740 --> 06:00:49,680 able to instances of this person to be able to be included inside sets Okay so 4446 06:00:49,680 --> 06:00:54,480 without making and without making this person hashable let me show you what 4447 06:00:54,480 --> 06:00:58,200 will happen if it is not hashable and you try to create a set out of it so 4448 06:00:58,200 --> 06:01:03,718 let's say that we have a foo ID in here and we say it is a uuid then we say let 4449 06:01:03,718 --> 06:01:09,600 Foo is a person with the ID of Foo ID its name is Foo 4450 06:01:09,600 --> 06:01:15,360 and its age is 20. all right then we create a bar person in here and we say 4451 06:01:15,360 --> 06:01:21,900 bar is pretty much similar to Foo and we say bar but we forget to change the ID 4452 06:01:21,900 --> 06:01:28,080 and bar is also using the foo ID its name is bar and its age is 30. all right 4453 06:01:28,080 --> 06:01:34,440 now we want to go ahead and create a set of Foo and bar so let's say we have 4454 06:01:34,440 --> 06:01:38,638 people and we say it is a set of person and it 4455 06:01:38,638 --> 06:01:43,860 is equal to Foo mbar now we should get an error ideally from Swift telling us 4456 06:01:43,860 --> 06:01:48,420 that these objects are not hashable you can see it says it does not conform to 4457 06:01:48,420 --> 06:01:53,040 protocol hashable all right so how do we do that how do we ensure that they 4458 06:01:53,040 --> 06:01:57,298 conform to hashable so let's go ahead and say that they conform to Hash Rule 4459 06:01:57,298 --> 06:02:01,200 and everything will just go fine nothing will happen in here you won't get any 4460 06:02:01,200 --> 06:02:06,058 errors okay and if you go in here and say people that count 4461 06:02:06,058 --> 06:02:11,040 let's go in here okay you will see unfortunately it is still two so what 4462 06:02:11,040 --> 06:02:16,500 happening here we said that well we are making this person hashable and it 4463 06:02:16,500 --> 06:02:21,900 should ideally not be placed twice in this set because uh it is pretty much 4464 06:02:21,900 --> 06:02:26,820 the same but if you look I mean same data but what happens in here is two 4465 06:02:26,820 --> 06:02:30,240 things when you when you create a structure and you just say it is 4466 06:02:30,240 --> 06:02:35,280 hashable without having any custom logic in it meaning that you didn't actually 4467 06:02:35,280 --> 06:02:39,900 tell Swift how to calculate the uniqueness of this object what Swift 4468 06:02:39,900 --> 06:02:44,520 does is that it looks at all the properties of that object and says okay 4469 06:02:44,520 --> 06:02:49,440 are all these properties unique themselves like are they hashable and if 4470 06:02:49,440 --> 06:02:56,040 you look at uuid is indeed hashable if you look at string it is hashable 4471 06:02:56,040 --> 06:03:01,980 uh let's see extension string hashable 4472 06:03:01,980 --> 06:03:05,458 somewhere it should have been made hashable I'm not sure if it is exactly 4473 06:03:05,458 --> 06:03:09,900 there we go extension string hashable and also if you look at the code for INT 4474 06:03:09,900 --> 06:03:16,500 it should also be extension and hashable there we go so since all these 4475 06:03:16,500 --> 06:03:19,920 three are hashable then Swift says okay I'm gonna calculate the hash value 4476 06:03:19,920 --> 06:03:24,480 myself then it says okay you created a person it has the ID let's just say it's 4477 06:03:24,480 --> 06:03:30,540 hash value is one let's say then it says oh the name is Foo the hash value is for 4478 06:03:30,540 --> 06:03:34,440 instance 10. I'm just making this up okay and the hash value for this guy 4479 06:03:34,440 --> 06:03:39,718 let's say is 20. all right then it comes to bar and says oh it has the same ID as 4480 06:03:39,718 --> 06:03:45,900 the other ones which is has a hash value of one but it's its name is bar so its 4481 06:03:45,900 --> 06:03:51,120 hash value is let's just say 30. and the age is also 30 with a hash value of 40 4482 06:03:51,120 --> 06:03:57,298 for instance okay so it says okay then you put both of these inside a set and 4483 06:03:57,298 --> 06:04:01,558 I'm gonna calculate these hashes 20 plus 10 plus one for instance okay this is 4484 06:04:01,558 --> 06:04:04,500 not how hashes are actually calculated but we're just going to plus them 4485 06:04:04,500 --> 06:04:09,840 together so 20 10 and 1 are going to be 31 and then we have 40 30 and one which 4486 06:04:09,840 --> 06:04:15,540 is going to be 70 a month so at 31 and 71 are not the same meaning that they're 4487 06:04:15,540 --> 06:04:20,040 basically not the same object and should both be placed inside the sets Okay so 4488 06:04:20,040 --> 06:04:23,760 that's how hashing basically Works within Swift okay 4489 06:04:23,760 --> 06:04:29,218 but what we may want to do is to tell Swift that hey we actually don't want 4490 06:04:29,218 --> 06:04:36,000 people with the same ID to be recognized as different people so what we want to 4491 06:04:36,000 --> 06:04:40,680 tell Swift is that if two people have the same ID then they're essentially the 4492 06:04:40,680 --> 06:04:45,780 same person okay and in order to give Swift more information about how it 4493 06:04:45,780 --> 06:04:51,180 should do our hashing we should go ahead and basically implement the hash 4494 06:04:51,180 --> 06:04:56,458 functionality somehow ourselves or at least inject our own logic within it so 4495 06:04:56,458 --> 06:05:01,798 let's create a person two object in here so a person to structure so now that 4496 06:05:01,798 --> 06:05:06,718 we've seen that example let's say a struct person two okay and we're gonna 4497 06:05:06,718 --> 06:05:10,860 grab let's actually grab this struct from here but instead we're just going 4498 06:05:10,860 --> 06:05:14,400 to call it person two so person two in here and we said that 4499 06:05:14,400 --> 06:05:19,440 it is hashable now if you make an object hashable you also have the ability to 4500 06:05:19,440 --> 06:05:23,218 override a function in here and not really override but also Implement 4501 06:05:23,218 --> 06:05:28,080 actually a function called hash into all right and this function comes in here 4502 06:05:28,080 --> 06:05:33,480 because we have we've conformed to the hashable protocol all right then in here 4503 06:05:33,480 --> 06:05:38,340 what you can do is to say hasher and then you combine you call the combine 4504 06:05:38,340 --> 06:05:43,440 function on it and then you basically hash the fields that you want to be 4505 06:05:43,440 --> 06:05:48,058 taken into account while Swift does its hashing so what this really did in here 4506 06:05:48,058 --> 06:05:54,420 is that it jumped over hashing name and age and instead only hashed ID within 4507 06:05:54,420 --> 06:05:59,340 the hashing mechanism of Swift all right so now that you've done that you also 4508 06:05:59,340 --> 06:06:03,540 need to tell Swift whether two objects are Equitable because you've just 4509 06:06:03,540 --> 06:06:06,180 implemented your own hashing functionality 4510 06:06:06,180 --> 06:06:11,760 and when you say something is hashable by default it's also Equitable and what 4511 06:06:11,760 --> 06:06:16,680 happens in here is that right now you set that take ID only into hashing 4512 06:06:16,680 --> 06:06:22,080 mechanism but in terms of equation because hashing is also doing equality 4513 06:06:22,080 --> 06:06:27,420 Swift if you don't intervene Swift goes and it says okay the hash values are the 4514 06:06:27,420 --> 06:06:30,958 same but these two objects are not really equal because by default Swift is 4515 06:06:30,958 --> 06:06:35,040 going to also equate all three properties so in here what we're going 4516 06:06:35,040 --> 06:06:39,540 to do is to say static func equality so we're going to overwrite equality as 4517 06:06:39,540 --> 06:06:43,980 well on the left hand side we say self and the right hand side itself then we 4518 06:06:43,980 --> 06:06:50,100 say Boolean and we say as long as the left hand side's ID is equal to the 4519 06:06:50,100 --> 06:06:54,298 right hand size ID then these two objects are equal so not only have we 4520 06:06:54,298 --> 06:06:59,340 changed the way a hashing works but we also need to change the way equality 4521 06:06:59,340 --> 06:07:03,958 Works otherwise they won't really come to an agreement with each other 4522 06:07:03,958 --> 06:07:07,378 okay now that we have that let's go ahead and 4523 06:07:07,378 --> 06:07:12,120 create a baz ID in here and we say it's a uuid all right 4524 06:07:12,120 --> 06:07:16,620 and then we say we create a baz person in here which is person two remember 4525 06:07:16,620 --> 06:07:21,958 create an object of type person two not person then we say baz ID its name is 4526 06:07:21,958 --> 06:07:27,718 bass and then we say it has or he has the age of 20 or she has the age of 20. 4527 06:07:27,718 --> 06:07:34,740 then we create a Cox value in here and we say q u x and we say person two and 4528 06:07:34,740 --> 06:07:41,520 then we say baz ID and the name is Cox and the age is 30. all right so you can 4529 06:07:41,520 --> 06:07:46,200 see now the ID is the same but all the other values are different however the 4530 06:07:46,200 --> 06:07:49,860 way we've done our hashing and equality is that we only take into account the ID 4531 06:07:49,860 --> 06:07:53,580 so even if their names are different but they're using the same ID then we 4532 06:07:53,580 --> 06:07:57,480 consider them to be the same person and that's why you can go in here it's say 4533 06:07:57,480 --> 06:08:04,080 if that's equal to Cox they are equal so this basically is invoking our equality 4534 06:08:04,080 --> 06:08:08,820 and you can see it comes in here okay but that's not the point that's not what 4535 06:08:08,820 --> 06:08:11,878 we're trying to do in here we actually want to add them to a set so let's say 4536 06:08:11,878 --> 06:08:19,378 let lets people people to and we create a set of bars and Cox in here and if you 4537 06:08:19,378 --> 06:08:23,340 look at the values inside people too it should just be one value 4538 06:08:23,340 --> 06:08:28,680 people too that count all right simply because our hashing intervene in here 4539 06:08:28,680 --> 06:08:34,080 and both these objects were considered to be the same object all right and if 4540 06:08:34,080 --> 06:08:38,638 you take the first item out of this you can get a person person two and then you 4541 06:08:38,638 --> 06:08:43,798 can say the first objects uh name give us the name all right and you can see it 4542 06:08:43,798 --> 06:08:49,620 is pass all right so a Cox was not inserted into our set simply because baz 4543 06:08:49,620 --> 06:08:53,820 was already there and Cox was considered to be the same object therefore it was 4544 06:08:53,820 --> 06:08:58,798 not inserted into the set all right so that's how you can go ahead and 4545 06:08:58,798 --> 06:09:06,058 Implement your own hashing value or hash value and equality all right that's 4546 06:09:06,058 --> 06:09:10,260 enough about sets let's talk now about dictionaries now dictionaries they're 4547 06:09:10,260 --> 06:09:14,100 also called Json objects and many other programming languages like like as such 4548 06:09:14,100 --> 06:09:19,080 as um not really Json objects yeah well kind of Json objects yeah there there 4549 06:09:19,080 --> 06:09:23,040 are keys and values basically okay and you define them using a square bracket 4550 06:09:23,040 --> 06:09:27,480 in um in Swift so you say user info and you 4551 06:09:27,480 --> 06:09:31,260 can create your dictionary and then you say keys are in this case string for 4552 06:09:31,260 --> 06:09:35,940 instance with a column and you separate the keys from the values using a column 4553 06:09:35,940 --> 06:09:42,420 and you can say the key is name the value is Foo this key is H and oops if 4554 06:09:42,420 --> 06:09:48,000 we can spell H and its value is 20 then you can say I have an address field in 4555 06:09:48,000 --> 06:09:52,260 here whose value is indeed another dictionary and you can say the address 4556 06:09:52,260 --> 06:09:58,500 has a line one and it is address line one then we have a postcode for instance 4557 06:09:58,500 --> 06:10:03,120 it's key as postcode and its value is one two three four five let's say all 4558 06:10:03,120 --> 06:10:07,260 right and this is completely valid a swift object if I haven't messed 4559 06:10:07,260 --> 06:10:11,940 anything up let's see Foo age address all right and we also have to tell Swift 4560 06:10:11,940 --> 06:10:16,860 that you can see it is a heterogeneous values because some values are strings 4561 06:10:16,860 --> 06:10:20,400 and some values are integers then we have to tell if there is a dictionary 4562 06:10:20,400 --> 06:10:25,320 with keys equal to string and values of any type all right without that it won't 4563 06:10:25,320 --> 06:10:28,620 work however if you didn't have this age in 4564 06:10:28,620 --> 06:10:33,240 here and we didn't have this address in here we could have just gone away by 4565 06:10:33,240 --> 06:10:36,600 defining our dictionary like this as Swift would have understood the data 4566 06:10:36,600 --> 06:10:41,580 type to be of key strings and values of strings as well but since we have keys 4567 06:10:41,580 --> 06:10:45,240 of string and value of integer and a key of string and a value of a dictionary 4568 06:10:45,240 --> 06:10:49,320 then we have to tell Swift that the keys are string and values could be anything 4569 06:10:49,320 --> 06:10:54,718 basically now you can grab values out of your dictionaries using type using 4570 06:10:54,718 --> 06:10:59,760 subscripting so you say user info grab the name and you can see it will give 4571 06:10:59,760 --> 06:11:04,740 you the value of Foo in here you can say give me the age user info give me the H 4572 06:11:04,740 --> 06:11:09,780 so you're basically giving it the keys and you're extracting the values for 4573 06:11:09,780 --> 06:11:15,000 those keys now you can say user info and then give me the address let's go in 4574 06:11:15,000 --> 06:11:20,218 here address at rest all right and since this is an 4575 06:11:20,218 --> 06:11:23,940 address dictionary coming back from here you may be hoping that okay since this 4576 06:11:23,940 --> 06:11:28,138 is an entire dictionary maybe I can type a key in here as well and get the 4577 06:11:28,138 --> 06:11:32,218 postcode all right and if you do this then you get an error because you've 4578 06:11:32,218 --> 06:11:37,200 told Swift that the values that come out of this uh dictionary are of type any 4579 06:11:37,200 --> 06:11:41,458 meaning that Swift Just believes that this is any and now you're trying to 4580 06:11:41,458 --> 06:11:45,540 tell Swift that this is not any and it's in fact a dictionary and it should go 4581 06:11:45,540 --> 06:11:49,980 into that dictionary and x and extract a value with a specific key and Swift Just 4582 06:11:49,980 --> 06:11:54,958 rejects that okay there's a dangerous way of doing that forcing Swift to 4583 06:11:54,958 --> 06:11:59,280 believe that this in itself is a dictionary and that is using the as 4584 06:11:59,280 --> 06:12:05,400 syntax but please don't ever do this in production applications and there there 4585 06:12:05,400 --> 06:12:09,120 are better ways of doing this so I just want to show you how it works you can 4586 06:12:09,120 --> 06:12:15,420 say get the address and force cast it to a dictionary of 4587 06:12:15,420 --> 06:12:20,540 type string and string you can see it because this has keys of string and 4588 06:12:20,540 --> 06:12:26,700 values of type string as well okay so after doing that uh then you can go 4589 06:12:26,700 --> 06:12:30,540 ahead and say give me the postcode on it all right and this should this should 4590 06:12:30,540 --> 06:12:35,760 work but in production applications really is not a good idea to do this so 4591 06:12:35,760 --> 06:12:39,780 let's see what happened actually found nil one on wrapping optional value and I 4592 06:12:39,780 --> 06:12:43,440 think it's because I I misspelled address basically 4593 06:12:43,440 --> 06:12:47,400 so it works but you should never do this because this will crash your application 4594 06:12:47,400 --> 06:12:52,500 should this key Either not exist or that its value shouldn't be of type string or 4595 06:12:52,500 --> 06:12:57,240 string your application will crash so please don't do this I'm just showing 4596 06:12:57,240 --> 06:13:01,798 you so that you know this syntax also exists okay if you want to extract the 4597 06:13:01,798 --> 06:13:06,780 keys and values out of a dictionary you can say user info dot keys and also you 4598 06:13:06,780 --> 06:13:11,400 can say userinfo.values and this will give these this will give you the keys 4599 06:13:11,400 --> 06:13:17,878 only you can see in here let's go in here the keys are age address name and 4600 06:13:17,878 --> 06:13:26,580 the values are 20. let's go here 20. Foo uh which is let's see where it is 4601 06:13:26,580 --> 06:13:31,740 it is 20. Foo and then this dictionary so you grab 4602 06:13:31,740 --> 06:13:36,298 basically only the keys or only the values out of your dictionary using that 4603 06:13:36,298 --> 06:13:41,280 syntax however it is more common that instead of just saying keys and values 4604 06:13:41,280 --> 06:13:46,020 you want to enumerate over the keys and values and their Associated values you 4605 06:13:46,020 --> 06:13:49,440 can because you can see in here we're only saying keys and only values but 4606 06:13:49,440 --> 06:13:53,700 what if you want to grab every key and its Associated value the Syntax for it 4607 06:13:53,700 --> 06:13:58,920 is for key and value in user info then you can print them out 4608 06:13:58,920 --> 06:14:04,260 key and value like this okay let's see if the playground can help us extract 4609 06:14:04,260 --> 06:14:09,240 these values so and the key says name value history you can see age address 4610 06:14:09,240 --> 06:14:14,280 and name are the keys and the values we can also perhaps get their history let's 4611 06:14:14,280 --> 06:14:20,700 see value it's oh the playground isn't so smart in 4612 06:14:20,700 --> 06:14:25,680 being able to print the value so let's instead print the values and see 4613 06:14:25,680 --> 06:14:30,058 if we can get them in the console uh like this so here are the values 4614 06:14:30,058 --> 06:14:33,840 basically okay and you can also print the keys as well so let's say we print 4615 06:14:33,840 --> 06:14:40,080 the keys and we print the value so uh the key of address has this value the 4616 06:14:40,080 --> 06:14:45,058 key of name has this full value and the key of H has the value of 20. all right 4617 06:14:45,058 --> 06:14:48,958 so we can do that as well let's just revert them back to how they work okay 4618 06:14:48,958 --> 06:14:54,718 now you can also have a where clause in your enumeration over keys and values so 4619 06:14:54,718 --> 06:15:03,600 let's say four key and value in user info where the value is an integer okay 4620 06:15:03,600 --> 06:15:09,718 and then you can say key and value so you see the only value that was an 4621 06:15:09,718 --> 06:15:15,480 integer had the key of H and it the value was of course the value of 20. all 4622 06:15:15,480 --> 06:15:21,298 right now you can also have multiple word Clauses so you're not 4623 06:15:21,298 --> 06:15:26,160 limited to only one where Clause so you can say four key and value and use for 4624 06:15:26,160 --> 06:15:33,058 info were the value is an INT and a key that 4625 06:15:33,058 --> 06:15:37,860 counts so the key is a string and we're saying it should contain only two uh 4626 06:15:37,860 --> 06:15:42,600 more than two characters then we say give us the key and the value all right 4627 06:15:42,600 --> 06:15:46,860 so the count is pretty much the length of the of the key 4628 06:15:46,860 --> 06:15:52,620 and then you can see that we got the same result because age is three letters 4629 06:15:52,620 --> 06:15:56,040 long and are conditions that it should be more than two but if in here we said 4630 06:15:56,040 --> 06:16:00,420 more than three then this will never be cost so we won't get any results in here 4631 06:16:00,420 --> 06:16:05,700 okay so I think that's actually quite enough right now about collections we 4632 06:16:05,700 --> 06:16:09,958 talked about arrays we talked about sets and we talked about also dictionaries 4633 06:16:09,958 --> 06:16:13,980 and some new formats and pattern matchings that you can do with these 4634 06:16:13,980 --> 06:16:19,320 collections they're very very useful and I think you need to really get and get 4635 06:16:19,320 --> 06:16:23,638 quite handy with these objects yourselves and in order to get a good 4636 06:16:23,638 --> 06:16:28,200 grasp of how they work I can just sit here and explain these for ages but 4637 06:16:28,200 --> 06:16:33,058 without practice and probably it will never really click so my advice is to go 4638 06:16:33,058 --> 06:16:36,780 ahead and create some sets arrays and dictionaries yourselves to get a good 4639 06:16:36,780 --> 06:16:40,798 grasp of how they work now that we talked about collections it 4640 06:16:40,798 --> 06:16:46,378 is good time that we start talking about equality and hashing as well I mean we 4641 06:16:46,378 --> 06:16:50,878 did touch upon this topic a little bit right now but we haven't fully covered 4642 06:16:50,878 --> 06:16:55,920 them equality and hashing they're like their own whole world of understanding 4643 06:16:55,920 --> 06:17:00,780 how they truly work and basically understanding them is the key to 4644 06:17:00,780 --> 06:17:06,120 understanding how sets for instance work and how equation generally in Swift 4645 06:17:06,120 --> 06:17:10,020 works and so I think it's very important that we dedicate it's 4646 06:17:10,020 --> 06:17:15,718 um a whole section just to equality and hashing so and that's what we're gonna 4647 06:17:15,718 --> 06:17:20,040 do right now so I'll see you there let's then go ahead and create a separate 4648 06:17:20,040 --> 06:17:26,520 playground for this so we say um blank and foreground sorry playground 4649 06:17:26,520 --> 06:17:32,638 and we say equality and hashing like this and ensure that 4650 06:17:32,638 --> 06:17:37,798 you're creating it in The Roots folder like this and then we just say create 4651 06:17:37,798 --> 06:17:43,440 and we import Foundation and we can get rid of the Explorer to 4652 06:17:43,440 --> 06:17:49,558 the left hand side now equality in Swift is provided using a protocol called 4653 06:17:49,558 --> 06:17:55,860 e-codable any object that conforms to the equilible protocol has to have a 4654 06:17:55,860 --> 06:18:01,740 function a static function and which is an equality function like this is pretty 4655 06:18:01,740 --> 06:18:06,718 much an operator and this function has to have two arguments one at left hand 4656 06:18:06,718 --> 06:18:10,558 side and right hand side both of the same exact type as the current 4657 06:18:10,558 --> 06:18:15,558 structural class implementing it now if you go ahead and create a person 4658 06:18:15,558 --> 06:18:22,378 structure in here and say that this person is conforming to the equatable 4659 06:18:22,378 --> 06:18:26,458 protocol and you say let's ID is a string and then you say let's name is a 4660 06:18:26,458 --> 06:18:29,700 string then we create two instances of this we 4661 06:18:29,700 --> 06:18:35,940 say let's Foo one is a person with the ID of one all right and then we say name 4662 06:18:35,940 --> 06:18:42,180 here is Foo then we create food too right here and we say the name is 4663 06:18:42,180 --> 06:18:49,500 actually bar then if you say if Fu one Foo one is equal to Food 2 then we say 4664 06:18:49,500 --> 06:18:53,820 they are equal with an exclamation mark in here because they shouldn't be they 4665 06:18:53,820 --> 06:18:58,860 are not equal otherwise okay so what happens in here is that by ensuring that 4666 06:18:58,860 --> 06:19:03,480 this person is Equitable all right let's also make sure that this is running 4667 06:19:03,480 --> 06:19:09,718 automatically by conforming the struct a person to Equitable as Swift goes in 4668 06:19:09,718 --> 06:19:13,260 through all the properties of the structure and ensures that they are 4669 06:19:13,260 --> 06:19:17,340 indeed themselves Equitable string by default conforms to the Equitable 4670 06:19:17,340 --> 06:19:22,020 protocol and so does this one so then Swift says okay then I understand that 4671 06:19:22,020 --> 06:19:26,100 it should be Equitable however if you go in here and say a struck dog and don't 4672 06:19:26,100 --> 06:19:30,240 make it Equitable and in hear you say this person should also have a dog all 4673 06:19:30,240 --> 06:19:33,600 of a sudden Swift will throw an error in here saying that oh I can't give you 4674 06:19:33,600 --> 06:19:38,340 equal Equitable by default because dog which is one of the properties of this 4675 06:19:38,340 --> 06:19:42,120 person's structure does not conform to Equitable if you want to get rid of this 4676 06:19:42,120 --> 06:19:47,100 just ensure that this dog is also Equitable which then gets rid of the 4677 06:19:47,100 --> 06:19:50,340 problem in here but the only problem we have in here that is that we need to 4678 06:19:50,340 --> 06:19:54,240 pass a dog instance in here but we're gonna remove all this dog reference in 4679 06:19:54,240 --> 06:19:58,980 here just wanted to show you how default implementation of Equitable basically 4680 06:19:58,980 --> 06:20:01,980 works it looks at all the properties and then make sure that they're Equitable 4681 06:20:01,980 --> 06:20:05,340 and then goes through all of them one by one compares the properties between 4682 06:20:05,340 --> 06:20:08,280 these two objects that we're comparing okay 4683 06:20:08,280 --> 06:20:14,400 now you can also override equality and uh you can basically say let's say that 4684 06:20:14,400 --> 06:20:19,558 you in your person uh structure you want to say any two persons that have the 4685 06:20:19,558 --> 06:20:24,120 same identifier should be considered equal so then you can say extension 4686 06:20:24,120 --> 06:20:27,780 person and you can see at the moment these two 4687 06:20:27,780 --> 06:20:32,218 objects right now before our extension they're marked as not equal all right 4688 06:20:32,218 --> 06:20:36,600 simply because their names are not equal but if you go to extension person and 4689 06:20:36,600 --> 06:20:40,558 then Define the static function equal equal like this and you say left hand 4690 06:20:40,558 --> 06:20:44,340 side itself like this and right hand side itself as 4691 06:20:44,340 --> 06:20:47,340 well and this function should return a Boolean indicating whether the two 4692 06:20:47,340 --> 06:20:51,120 objects are equal or not then we say if the left hand side's ID is equal to 4693 06:20:51,120 --> 06:20:54,660 right hand size ID then these two should be considered equal now all of a sudden 4694 06:20:54,660 --> 06:20:58,260 you see that this will be flipped to they are equal 4695 06:20:58,260 --> 06:21:02,878 previously before this extension this branch of code was being executed 4696 06:21:02,878 --> 06:21:06,718 because by default there were not equal since they had different names however 4697 06:21:06,718 --> 06:21:10,500 with our extension in place since we're only comparing the IDS then they're 4698 06:21:10,500 --> 06:21:13,500 marked as equal so if you comment your code out you can see all of a sudden 4699 06:21:13,500 --> 06:21:17,100 that this Branch will stop being executed and instead this Branch will 4700 06:21:17,100 --> 06:21:21,540 get executed all right so that's how you can create your own 4701 06:21:21,540 --> 06:21:25,680 equality on custom objects so we can comment this guy out 4702 06:21:25,680 --> 06:21:29,280 apart from structures you can also Implement custom equality on 4703 06:21:29,280 --> 06:21:34,558 enumerations let's say that we have an enum in here we call animal type and we 4704 06:21:34,558 --> 06:21:41,520 have a case where a dog and we ask for the breed and also we have a cat and we 4705 06:21:41,520 --> 06:21:46,378 ask for the breed okay now let's say that you want to compare these 4706 06:21:46,378 --> 06:21:51,360 um to with each other if you go ahead and say let's dog and say is an animal 4707 06:21:51,360 --> 06:21:56,958 with a type of dog with its breed is a labradoodle and then you say let's 4708 06:21:56,958 --> 06:22:03,780 whiskers is an animal type another dog basically exactly of 4709 06:22:03,780 --> 06:22:08,878 the same type then if you go ahead and say if dog equal to whiskers let's just 4710 06:22:08,878 --> 06:22:13,798 change this to maybe dog two dog one and Dot two and then we say if 4711 06:22:13,798 --> 06:22:19,620 dog one equal to dog two like this you can see that you get an air from Swift 4712 06:22:19,620 --> 06:22:23,700 because by default animal type is not Equitable you can go ahead in here and 4713 06:22:23,700 --> 06:22:27,660 say okay well I'll make it Equitable does this work you'll be surprised to 4714 06:22:27,660 --> 06:22:32,280 see that actually my default what Swift does is it looks at these values and 4715 06:22:32,280 --> 06:22:36,540 says let me let's put some values in here and say they are equal 4716 06:22:36,540 --> 06:22:44,340 like this otherwise we say else they are not equal all right so since dogmon and 4717 06:22:44,340 --> 06:22:48,660 dog 2 we actually are giving them the same values in here then suit by default 4718 06:22:48,660 --> 06:22:52,440 says oh they're equal but if you change the value inside this breed for instance 4719 06:22:52,440 --> 06:22:56,340 then Swift says they're not equal so Swift does the same thing that it does 4720 06:22:56,340 --> 06:23:00,958 with structures as it does with enums it goes through all the properties of those 4721 06:23:00,958 --> 06:23:05,040 enum cases and then make sure that they're Equitable if they are it will 4722 06:23:05,040 --> 06:23:09,000 just call the equation function on those parameters as well and Compares them 4723 06:23:09,000 --> 06:23:12,540 with each other if all those they're equal to each other and the case is 4724 06:23:12,540 --> 06:23:18,660 equal to the other case as well then the enum cases are marked as equal however 4725 06:23:18,660 --> 06:23:24,260 you can go ahead and change this implementation so you can say extension 4726 06:23:24,260 --> 06:23:28,558 extension animal type and let's just remove the Equitable from here and we 4727 06:23:28,558 --> 06:23:32,580 say animal type becomes Equitable in this extension all right 4728 06:23:32,580 --> 06:23:37,500 and then we go ahead and Implement a an extension and sorry the static Funk left 4729 06:23:37,500 --> 06:23:41,458 hand side itself and right hand side itself as well and then in here we say 4730 06:23:41,458 --> 06:23:46,558 bull all right so now what we want to do in here is to compare the breeds with 4731 06:23:46,558 --> 06:23:51,298 each other so we say we switch the left hand side and the right hand side then 4732 06:23:51,298 --> 06:23:57,360 we say in case and we have a dog with the left hand side breed and another dog 4733 06:23:57,360 --> 06:24:02,638 with their right hand side breed then they're considered equal as long as 4734 06:24:02,638 --> 06:24:06,240 the left hand side breed is equal to right hand side breed we do the same 4735 06:24:06,240 --> 06:24:11,160 thing for cats so we say if we get a cat in here and a cat in here then they're 4736 06:24:11,160 --> 06:24:15,958 equal to each other as long as their breeds are equal and since this pattern 4737 06:24:15,958 --> 06:24:19,558 matching is the exact same thing between dog and cat you can see they're getting 4738 06:24:19,558 --> 06:24:22,680 left hand side breed right hand side Bree and the same thing in here you can 4739 06:24:22,680 --> 06:24:26,820 remove this coating here and just put a comma and remove this case as well all 4740 06:24:26,820 --> 06:24:29,280 right so they're basically doing the same thing 4741 06:24:29,280 --> 06:24:33,420 and then you can go ahead and say anything else they're considered not 4742 06:24:33,420 --> 06:24:38,218 equal to each other okay so as long as it's a dog and a dog and their breeds 4743 06:24:38,218 --> 06:24:42,120 are the same then it's considered to be the same and if it's a cat and a cat 4744 06:24:42,120 --> 06:24:45,298 then they're considered to be the same as well 4745 06:24:45,298 --> 06:24:50,160 so let's see what we got and we got this oh we have to return this of course we 4746 06:24:50,160 --> 06:24:56,218 can't just write that statement in the playground good then we can go ahead and 4747 06:24:56,218 --> 06:25:00,240 um basically we've now created an animal type let's go ahead and create an animal 4748 06:25:00,240 --> 06:25:06,540 now so we say it's struct and we say animal animal in here animal 4749 06:25:06,540 --> 06:25:12,180 and we said let's name is a strain and then we say let's type is an animal 4750 06:25:12,180 --> 06:25:16,558 type okay and since both string and animal type by this point are Equitable 4751 06:25:16,558 --> 06:25:22,558 you can make this animal also conform to Equitable all right however what we want 4752 06:25:22,558 --> 06:25:27,780 to do is to say okay the animal equality has to only look at the animal type we 4753 06:25:27,780 --> 06:25:31,500 don't want it to look at the animal name that is the default behavior that Swift 4754 06:25:31,500 --> 06:25:34,920 looks at all the properties but in this case we just want to look at the animal 4755 06:25:34,920 --> 06:25:40,080 type all right so let's say that then we override the static oops static Funk 4756 06:25:40,080 --> 06:25:44,280 equal equal and we say left hand side itself and right hand side itself as 4757 06:25:44,280 --> 06:25:48,900 well and we return a Boolean okay and we only look at the types so we say left 4758 06:25:48,900 --> 06:25:52,440 hand side type should be equal to right hand side type otherwise they're not 4759 06:25:52,440 --> 06:25:56,760 equal okay then we can go ahead and say let cat one 4760 06:25:56,760 --> 06:26:03,058 is an animal and its name is whiskers like this all right and it's animal type 4761 06:26:03,058 --> 06:26:09,120 is actually a cat then we say it is a cat of type Street gap of the breed 4762 06:26:09,120 --> 06:26:15,840 Street cow okay let's put that in here and this is also a shorthand of writing 4763 06:26:15,840 --> 06:26:19,740 um the animal types instead of saying animal type in here you can just say dot 4764 06:26:19,740 --> 06:26:23,520 cat so instead of doing this you can just do the shorthand and so it will 4765 06:26:23,520 --> 06:26:27,420 understand the code anyways let's copy this code and then we say cats number 4766 06:26:27,420 --> 06:26:33,540 two and its name is whoosh okay just like that and it's also a straight cap 4767 06:26:33,540 --> 06:26:39,180 so looking at our equality functionality in here we only look at Types on animal 4768 06:26:39,180 --> 06:26:43,440 in order to to determine if they're equal to each other or not so then we 4769 06:26:43,440 --> 06:26:51,058 should be able to go and say if cat1 is equal to cat2 they are equal because of 4770 06:26:51,058 --> 06:26:55,020 their breed actually type because of their type 4771 06:26:55,020 --> 06:27:00,120 else and they are not equal all right and you can see that this branch of the 4772 06:27:00,120 --> 06:27:03,780 code is being executed simply because our equality custom equality on animal 4773 06:27:03,780 --> 06:27:09,420 only compares the animal types and since they have the exact same type of cat and 4774 06:27:09,420 --> 06:27:14,040 Street cat then our code works and you you can actually go and remove this 4775 06:27:14,040 --> 06:27:18,480 implementation on animal type because this pretty much is the same thing that 4776 06:27:18,480 --> 06:27:22,860 Swift provides Equitable and you can see the code will be executed just like 4777 06:27:22,860 --> 06:27:26,940 before so no difference really so it's up to you if you want to do custom 4778 06:27:26,940 --> 06:27:32,520 implementation of Equitable or you want to let Swift deduce this on its own if 4779 06:27:32,520 --> 06:27:36,540 Swift can already deduce this on its own which it can you shouldn't really go and 4780 06:27:36,540 --> 06:27:40,798 write an exact same implementation so this this is pretty much just redundant 4781 06:27:40,798 --> 06:27:45,420 but if your custom implementation of Equitable adds some functionality to how 4782 06:27:45,420 --> 06:27:49,740 swift does it by default then please go ahead and add your own Equitable to your 4783 06:27:49,740 --> 06:27:55,680 custom types okay so we can now we've had a look at Equitable let's look add a 4784 06:27:55,680 --> 06:27:59,760 hashable and we've already talked about this a little bit before but let's just 4785 06:27:59,760 --> 06:28:03,298 talk a little bit more in details about it just like Equitable hashable also 4786 06:28:03,298 --> 06:28:07,378 looks at all properties of a struct or a class to make that start or class 4787 06:28:07,378 --> 06:28:12,120 hashable so if you say struct house and we make it hashable then we say let's 4788 06:28:12,120 --> 06:28:17,700 number is int and we say let number of bedrooms 4789 06:28:17,700 --> 06:28:24,120 is an INT then we say let house one is house with the number of one two three 4790 06:28:24,120 --> 06:28:29,878 and number of bedrooms is let's say two all right and then we say house one and 4791 06:28:29,878 --> 06:28:33,240 you can see now you have a property in here called hash value and that is 4792 06:28:33,240 --> 06:28:35,878 coming from the hashable protocol in here 4793 06:28:35,878 --> 06:28:40,138 then we go ahead and create another house we call it house number two in 4794 06:28:40,138 --> 06:28:45,180 here okay house two and its number is one two three but it's number of 4795 06:28:45,180 --> 06:28:49,980 bedrooms is three and then we print out its hash value in here as well now you 4796 06:28:49,980 --> 06:28:54,298 can see these hash values are different simply means that they basically if you 4797 06:28:54,298 --> 06:28:58,200 create a set with house one and house two they can occupy their own space and 4798 06:28:58,200 --> 06:29:02,280 not overwrite each other however if you go in here and say number of bedroom and 4799 06:29:02,280 --> 06:29:06,780 bedrooms is two then you should ideally in here see the exact same hash value 4800 06:29:06,780 --> 06:29:12,000 meaning that you cannot put both houses inside the same set and expect them both 4801 06:29:12,000 --> 06:29:16,740 to basically appear in the set one is going to overwrite the other one okay so 4802 06:29:16,740 --> 06:29:22,200 if we go ahead and create a setting here we say let houses is a set of house one 4803 06:29:22,200 --> 06:29:25,620 and house two and please note that I changed this back so it's now number of 4804 06:29:25,620 --> 06:29:30,360 bedrooms two and this one is three then if we say houses dot count then you can 4805 06:29:30,360 --> 06:29:34,740 see we get two in here because none is overwriting the other one 4806 06:29:34,740 --> 06:29:39,058 let's see if the playground is going to be able to update soon hopefully 4807 06:29:39,058 --> 06:29:43,200 even if it doesn't show the count we can still see in here that we have one house 4808 06:29:43,200 --> 06:29:46,320 in here and another one here and now the count is also being displayed right 4809 06:29:46,320 --> 06:29:52,798 there okay really good you can overwrite the uh how hashing of course Works we've 4810 06:29:52,798 --> 06:29:56,280 already had a look at this and when we talk about collections but let's have a 4811 06:29:56,280 --> 06:30:01,378 look at another example so we say a struct numbered house okay and we say it 4812 06:30:01,378 --> 06:30:06,000 is hashable like this and we say let's number is int 4813 06:30:06,000 --> 06:30:11,820 and then we say let's number of uh bedrooms is an end and this is pretty 4814 06:30:11,820 --> 06:30:16,558 much the copy of the house structure but we had to give it another name and 4815 06:30:16,558 --> 06:30:19,620 because you can't have two structures with the same name in the same code 4816 06:30:19,620 --> 06:30:25,020 scope in Swift okay then in here we're going to go and overwrite this a hashing 4817 06:30:25,020 --> 06:30:30,480 mechanism so we say hash into and we say we only want to combine the number into 4818 06:30:30,480 --> 06:30:34,798 the hasher so we say combine the number and this simply means that as long as 4819 06:30:34,798 --> 06:30:38,780 two houses have the same number then they're at the same house pretty much 4820 06:30:38,780 --> 06:30:43,920 when it comes to their hash values okay however this doesn't mean that they're 4821 06:30:43,920 --> 06:30:48,360 equal you have to override equality as well so say static Funk equal and we say 4822 06:30:48,360 --> 06:30:52,080 on the left hand side we get self and the right hand side we get cell self as 4823 06:30:52,080 --> 06:30:55,500 well then we say this returns a Boolean and 4824 06:30:55,500 --> 06:31:00,180 then we say as long as the numbers so we say left hand side number is should be 4825 06:31:00,180 --> 06:31:04,920 equal to right hand sign number and then both houses are considered to be equal 4826 06:31:04,920 --> 06:31:09,120 to each other in that case Okay so let's create let house three and please make 4827 06:31:09,120 --> 06:31:13,920 sure you create a numbered housing here not a house it's house number we say one 4828 06:31:13,920 --> 06:31:18,718 two three and number of bedrooms is two okay so as a house number one two three 4829 06:31:18,718 --> 06:31:24,480 then we create another house we call it house four in here okay like that 4830 06:31:24,480 --> 06:31:28,500 and then we say it is a numbered house and the exact same number as this house 4831 06:31:28,500 --> 06:31:33,740 however it has three bedrooms okay then we create a set of these we say houses 4832 06:31:33,740 --> 06:31:40,138 at three and four it is a set of house three and house four and then if you 4833 06:31:40,138 --> 06:31:44,760 look at houses three and four count you can see there's only one object inside 4834 06:31:44,760 --> 06:31:49,740 this set simply because house three and four they can only consume the same 4835 06:31:49,740 --> 06:31:54,120 space in our sets and simply because their hash value is the same you can see 4836 06:31:54,120 --> 06:31:58,798 in here and let's see if playground is going to be able to update our codes 4837 06:31:58,798 --> 06:32:03,558 hopefully soon if I close this one maybe it's just gone crazy a little bit 4838 06:32:03,558 --> 06:32:08,280 let's say automatically run hopefully it can run the code so you can 4839 06:32:08,280 --> 06:32:12,000 see there's only one value in here and if you say houses three and four get the 4840 06:32:12,000 --> 06:32:17,520 first item then it gives us a numbered house and then we can say get its house 4841 06:32:17,520 --> 06:32:22,920 number bedrooms and it says the number of bedrooms is two and the reason behind 4842 06:32:22,920 --> 06:32:27,240 this is that house Ford could not be placed in the set simply because there 4843 06:32:27,240 --> 06:32:32,940 was a house already in the set with the same hash value and you can also look at 4844 06:32:32,940 --> 06:32:38,458 the house at three hash value and house for hash values and they should pretty 4845 06:32:38,458 --> 06:32:42,360 much be the same simply because the hashing algorithm is only taking the 4846 06:32:42,360 --> 06:32:45,558 house number into account so you can say house three 4847 06:32:45,558 --> 06:32:51,600 house three number dot hash value and it should pretty much be unique 4848 06:32:51,600 --> 06:32:56,760 as well and you can see they're exactly the same thing okay and house for that 4849 06:32:56,760 --> 06:33:02,940 number hash value there the same as the entire hash value of the house okay 4850 06:33:02,940 --> 06:33:09,900 another example now EMS are by default hashable even without raw values so I'll 4851 06:33:09,900 --> 06:33:15,600 show you in here we say enum car part car parts like this and we say case a 4852 06:33:15,600 --> 06:33:23,058 roof uh case tire and case trunk then in here we say let's unique Parts 4853 06:33:23,058 --> 06:33:30,600 is a set of car parts okay and it's equal to a set that contains a 4854 06:33:30,600 --> 06:33:34,200 roof it contains Tire 4855 06:33:34,200 --> 06:33:39,780 it contains another roof and then a trunk so since this is a set of car 4856 06:33:39,780 --> 06:33:45,120 parts and it doesn't have any raw values like we're not doing it like this 4857 06:33:45,120 --> 06:33:49,200 so they don't have raw values if you in here say unique part oh actually we can 4858 06:33:49,200 --> 06:33:53,400 see the value already here you can see it only contains trunk roof and tire so 4859 06:33:53,400 --> 06:33:58,620 it doesn't contain two roofs that's what I'm trying to get to so if you create a 4860 06:33:58,620 --> 06:34:02,940 simple enum in Swift without any raw values or any Associated values it's by 4861 06:34:02,940 --> 06:34:09,718 default hashable and Equitable all right that is the whole point now if you have 4862 06:34:09,718 --> 06:34:14,878 an enum with um with Associated values then you can 4863 06:34:14,878 --> 06:34:18,718 basically go ahead and change the hashing mechanism yourself so let's say 4864 06:34:18,718 --> 06:34:25,200 that we have an enum in here we call it house type and it has a big house and we 4865 06:34:25,200 --> 06:34:30,780 say its Associated value is a numbered house and we say case small house it is 4866 06:34:30,780 --> 06:34:34,260 a numbered house like this and then you can go ahead in 4867 06:34:34,260 --> 06:34:39,298 here and say this is hashable all right so as you do that Swift looks at the 4868 06:34:39,298 --> 06:34:44,400 properties that are inside this enum and it understands that oh this big house is 4869 06:34:44,400 --> 06:34:48,120 of course hashable because it's an inum case however it has an Associated value 4870 06:34:48,120 --> 06:34:52,378 then it looks at the associated value and says is this value hashable then it 4871 06:34:52,378 --> 06:34:56,340 goes to numbered house and it says yep it is hashable then it implements 4872 06:34:56,340 --> 06:35:02,160 hashable by default for you on this house type okay so then you can go ahead 4873 06:35:02,160 --> 06:35:10,080 and basically add these into some sort of a set so let's go ahead and we say we 4874 06:35:10,080 --> 06:35:15,780 create two big houses we say big house number one is a house type 4875 06:35:15,780 --> 06:35:22,680 big house like this and it has a numbered house inside it like this all 4876 06:35:22,680 --> 06:35:27,120 right and this number it has has a few properties it has a number and we say 4877 06:35:27,120 --> 06:35:31,940 number one and it is number of bedrooms is one as well so we have a big house 4878 06:35:31,940 --> 06:35:36,660 and that's number one in that street for instance and it has one bedroom for some 4879 06:35:36,660 --> 06:35:41,400 reason a big house with one bedroom only then we say a big house number two in 4880 06:35:41,400 --> 06:35:46,440 here okay let's get rid of this Bottom bar then we say it is also a big house 4881 06:35:46,440 --> 06:35:51,000 at number one and total number of bedrooms is one on that one as well then 4882 06:35:51,000 --> 06:35:56,878 we create a small house so we say small house one and like this small house one 4883 06:35:56,878 --> 06:36:03,600 it is a small house house and we say it is at number one as well and it's number 4884 06:36:03,600 --> 06:36:09,000 of bedrooms is one all right so now we have three houses with the same number 4885 06:36:09,000 --> 06:36:13,980 and two of them are actually the same house type as well so what's going to 4886 06:36:13,980 --> 06:36:18,660 happen if we go and put these inside a set so we say all houses is a set of 4887 06:36:18,660 --> 06:36:24,000 house type and is equal to a set with a big house 4888 06:36:24,000 --> 06:36:29,458 big house one big house two and small house one all right 4889 06:36:29,458 --> 06:36:34,320 so if you say all houses the count in here then let's see if the playground 4890 06:36:34,320 --> 06:36:38,340 can resolve this you can see there's only two objects in here the reason is 4891 06:36:38,340 --> 06:36:42,420 that big house one and Big House 2 are considered to have the same hash value 4892 06:36:42,420 --> 06:36:47,520 simply because that their numbered houses have the same hash value and 4893 06:36:47,520 --> 06:36:52,138 their cases have the same hash value however small house one is of type small 4894 06:36:52,138 --> 06:36:56,520 house not big house though it's numbered house has the same hash value as the 4895 06:36:56,520 --> 06:37:00,840 other numbered houses however the enum case itself also has a hash hash value 4896 06:37:00,840 --> 06:37:06,298 therefore in here you can see if I say all houses first and all houses actually 4897 06:37:06,298 --> 06:37:10,980 let's see if you can get the values inside the sets like this you can see we 4898 06:37:10,980 --> 06:37:16,558 have a let's see oh you can see the first one is a big house at number one 4899 06:37:16,558 --> 06:37:23,340 and if we say all houses last uh let's see if you can get the first does it 4900 06:37:23,340 --> 06:37:28,320 have a last item no it doesn't we can get the first unfortunately and let's 4901 06:37:28,320 --> 06:37:33,840 just say four value in all houses and then we type the value out in here let's 4902 06:37:33,840 --> 06:37:39,600 maybe even print the value like this so you will see then the first elements 4903 06:37:39,600 --> 06:37:45,958 inside all houses is a numbered house is a small house with that numbered house 4904 06:37:45,958 --> 06:37:49,378 and the second one is a big house meaning that the two big houses couldn't 4905 06:37:49,378 --> 06:37:54,360 actually occupy two separate spaces in the set simply because their hash values 4906 06:37:54,360 --> 06:38:01,260 are the same okay so I think that's actually enough right now about equality 4907 06:38:01,260 --> 06:38:05,218 and hashing we've talked quite a lot about them right now and I think you get 4908 06:38:05,218 --> 06:38:08,160 basically the idea so there's two different things you have to implement 4909 06:38:08,160 --> 06:38:12,718 or think about when it comes to equality hashing one is the hash of value which 4910 06:38:12,718 --> 06:38:16,860 determines whether two objects should consume the same space inside a set but 4911 06:38:16,860 --> 06:38:20,820 also you have to implement equality which determines whether two objects are 4912 06:38:20,820 --> 06:38:25,798 actually equal to each other okay and also you may sometimes just need objects 4913 06:38:25,798 --> 06:38:30,718 to be Equitable not hashable in in which case you can just implement it Equitable 4914 06:38:30,718 --> 06:38:34,620 protocol or conform to the Equitable protocol as long as all the properties 4915 06:38:34,620 --> 06:38:37,860 inside your structural class are equatable then you don't have to 4916 06:38:37,860 --> 06:38:41,820 implement a custom equality static function however you can always go ahead 4917 06:38:41,820 --> 06:38:46,260 and change the default implementation of both hashable and Equitable as well all 4918 06:38:46,260 --> 06:38:50,700 right now we're done with equality and hashing so let's start talking about 4919 06:38:50,700 --> 06:38:55,440 custom operators I'm going to close this playground in here so let's create a new 4920 06:38:55,440 --> 06:39:01,558 one a blank playground like this and then we call this one 4921 06:39:01,558 --> 06:39:05,638 custom operators all right and we create the playground 4922 06:39:05,638 --> 06:39:10,860 then we say import Foundation like that and then we can get rid of the Explorer 4923 06:39:10,860 --> 06:39:15,860 to the left hand side like this and we can run our playground 4924 06:39:15,860 --> 06:39:21,000 automatically now we've talked about operators to this point uh quite a bit 4925 06:39:21,000 --> 06:39:24,958 actually but we haven't talked about creating so many custom operators and 4926 06:39:24,958 --> 06:39:29,160 that's what we're going to do in this section of the code so let's say that 4927 06:39:29,160 --> 06:39:33,780 you have a first name and which is a string optional string and you say it is 4928 06:39:33,780 --> 06:39:39,000 actually equal to Foo though it is set as being the optional string and then 4929 06:39:39,000 --> 06:39:43,558 you create a last name in here and then you say bar now if you want to get the 4930 06:39:43,558 --> 06:39:48,120 full name and you say it should be equal to first name plus last name you'll see 4931 06:39:48,120 --> 06:39:52,378 that you get an error from Swift saying that this operator it is not defined 4932 06:39:52,378 --> 06:39:56,638 between you can see there is no operator that exists that matches this particular 4933 06:39:56,638 --> 06:40:01,080 signature left hand side optional string and right hand slide optional string if 4934 06:40:01,080 --> 06:40:04,620 these were not optional strings then you would have this operator you can see 4935 06:40:04,620 --> 06:40:08,520 that the error goes away let's see if we can get the definition actually for this 4936 06:40:08,520 --> 06:40:15,420 one A Plus operator I don't think we can unfortunately let's see a static Funk 4937 06:40:15,420 --> 06:40:18,240 Plus here we go there is that function 4938 06:40:18,240 --> 06:40:24,360 signature all right however the Swift Foundation framework hasn't defined the 4939 06:40:24,360 --> 06:40:28,200 same operator for optional strings so we can actually go ahead and do that 4940 06:40:28,200 --> 06:40:34,558 ourselves so let's say we have a funk plus and its left hand side is an 4941 06:40:34,558 --> 06:40:38,580 optional string and its right hand side is an optional string as well and it 4942 06:40:38,580 --> 06:40:42,420 returns an optional string okay then we go inside the function implementation 4943 06:40:42,420 --> 06:40:48,180 and we switch the left hand side and the right hand side if they are both none 4944 06:40:48,180 --> 06:40:53,458 meaning that they're both null then we return nil or actually not null but nil 4945 06:40:53,458 --> 06:40:57,900 Swift is one language that is chosen to use nil instead of null then we say okay 4946 06:40:57,900 --> 06:41:05,458 if then we get the left hand side so if we say case let we have some value on 4947 06:41:05,458 --> 06:41:08,820 the left hand side but no values to the right hand side 4948 06:41:08,820 --> 06:41:12,240 then we return the value to the left hand side so if you only have the first 4949 06:41:12,240 --> 06:41:16,440 name but not the last name then we return the first name as the full name 4950 06:41:16,440 --> 06:41:21,360 we do the opposite of this for last name as well so if the first name is is nil 4951 06:41:21,360 --> 06:41:25,980 but the right hand side has the value meaning that there is a is a family name 4952 06:41:25,980 --> 06:41:32,760 then we say return that value all right and we can join these two together like 4953 06:41:32,760 --> 06:41:36,540 this because they have the same pattern okay 4954 06:41:36,540 --> 06:41:44,700 and then we say if both of them have a value so we say sum left hand side and 4955 06:41:44,700 --> 06:41:50,218 some if I can spell some right hand side then we say return the left hand side 4956 06:41:50,218 --> 06:41:54,298 plus the right hand side okay as soon as you're done writing this function you 4957 06:41:54,298 --> 06:41:58,260 can see all of a sudden the errors go away and all of a sudden full name is 4958 06:41:58,260 --> 06:42:04,200 indeed equal to Foo bar all right so um we can also add a space in here 4959 06:42:04,200 --> 06:42:10,138 perhaps or add a space before bar so it becomes Foo plus bar right here okay 4960 06:42:10,138 --> 06:42:15,360 so that's how you can create a simple custom operator in Swift okay and I 4961 06:42:15,360 --> 06:42:18,420 think we've actually looked at something similar to this before maybe even 4962 06:42:18,420 --> 06:42:23,760 something more complicated all right now we haven't yet created our own unary 4963 06:42:23,760 --> 06:42:29,160 prefix operator this one was a binary in fix operator because it works with two 4964 06:42:29,160 --> 06:42:34,740 or binary and things two things therefore binary so this is a binary in 4965 06:42:34,740 --> 06:42:38,760 fix it is binary because it works with two operators and sorry with two 4966 06:42:38,760 --> 06:42:43,620 parameters and it's an infix operator because it says in between two values 4967 06:42:43,620 --> 06:42:46,798 okay however we haven't looked at unary 4968 06:42:46,798 --> 06:42:51,540 prefix operators so let's create a unary prefix operator let's have a look at an 4969 06:42:51,540 --> 06:42:56,580 example let's say that we have a lowercase naming here which is equal to 4970 06:42:56,580 --> 06:43:02,180 foobar and we want to turn it into uppercase Name by saying lowercase name 4971 06:43:02,180 --> 06:43:07,080 uppercase like this and this operator doesn't exist at the moment so you can 4972 06:43:07,080 --> 06:43:13,200 see it is we want to say unary unary prefix it is unary because it only works 4973 06:43:13,200 --> 06:43:17,878 with one argument to its left hand side and that's why it is called prefix 4974 06:43:17,878 --> 06:43:23,520 because it is it basically works with some actually no that is a that is a 4975 06:43:23,520 --> 06:43:28,138 suffix I would say that we need to move this here okay so this is a unary prefix 4976 06:43:28,138 --> 06:43:32,160 because it operate cases whatever it comes to its right hand side so prefix 4977 06:43:32,160 --> 06:43:36,900 because it is previous to the argument to its right hand side okay 4978 06:43:36,900 --> 06:43:41,100 so what we can do then is to go ahead and implement this operator but before 4979 06:43:41,100 --> 06:43:45,600 doing that since it is not an infix operator you actually have to Swift you 4980 06:43:45,600 --> 06:43:49,620 have to tell Swift that it is a prefix operator so you do that by saying prefix 4981 06:43:49,620 --> 06:43:54,420 operator it like this so you first tell Swift that this is a prefix operator 4982 06:43:54,420 --> 06:43:59,878 then you go ahead and Define a function for it so you say prefix func like this 4983 06:43:59,878 --> 06:44:04,020 oopsie lazy all right and then we work with a value 4984 06:44:04,020 --> 06:44:08,100 of type screen and we return a value of type string then we take the value and 4985 06:44:08,100 --> 06:44:13,378 we say uppercased oopsie Daisy uppercase like that now all of a sudden you can 4986 06:44:13,378 --> 06:44:18,360 see that this error will go away and our Foo BAR value will turn into Foo bar as 4987 06:44:18,360 --> 06:44:23,180 uppercase okay so that that is how you do a prefix operator 4988 06:44:23,180 --> 06:44:27,180 in Swift you have to first Define it as a prefix operator then you create the 4989 06:44:27,180 --> 06:44:33,660 function for it similar to this we can also create a unary postfix operators so 4990 06:44:33,660 --> 06:44:39,120 let's say that we have for instance um a name here which is fool bar and we 4991 06:44:39,120 --> 06:44:45,660 want to turn it into a star star star Fubar star star star like that okay so 4992 06:44:45,660 --> 06:44:49,798 whatever string we give our operator we wanted to prefix it with three stars and 4993 06:44:49,798 --> 06:44:54,480 a space and then a space and three stars after it okay so we say left with stars 4994 06:44:54,480 --> 06:45:00,420 is equal to lowercase name and then make sure you start it out so meanwhon a 4995 06:45:00,420 --> 06:45:06,120 unary post fix operator it is unary because it works only with one object to 4996 06:45:06,120 --> 06:45:09,780 its left hand side and therefore it's called post fix because it comes after 4997 06:45:09,780 --> 06:45:15,480 the element that it works with so let's define it we say postfix operator star 4998 06:45:15,480 --> 06:45:21,240 and then we say postfix func star it takes a value of type string and it 4999 06:45:21,240 --> 06:45:26,940 returns a string as well and what it does is that it just says star star 5000 06:45:26,940 --> 06:45:32,820 space value star star star okay and then you can see the value printed here will 5001 06:45:32,820 --> 06:45:36,900 then be star star Fubar space star star okay 5002 06:45:36,900 --> 06:45:43,740 so you can also Define your own custom binary infix operators on completely 5003 06:45:43,740 --> 06:45:49,138 unrelated types so it what we've looked at so far is that every time you work 5004 06:45:49,138 --> 06:45:53,040 with a binary infix operators both left hand side and right hand side were of 5005 06:45:53,040 --> 06:45:57,000 the same type however what happens if you have for instance a struct in here 5006 06:45:57,000 --> 06:46:02,820 let's say we have a struct of person and we say let name is a 5007 06:46:02,820 --> 06:46:08,820 string and then you have a struct family and then you say let members is an array 5008 06:46:08,820 --> 06:46:15,958 of persons okay then you go ahead and you say that you for instance have a mom 5009 06:46:15,958 --> 06:46:24,000 let's mom is person with the name of mom then we create a dad in here Dad we say 5010 06:46:24,000 --> 06:46:30,058 that and then we say Sun sun is Sun like that then we create 5011 06:46:30,058 --> 06:46:36,780 dollars so we say daughter one and his daughter one and daughter two all right 5012 06:46:36,780 --> 06:46:41,218 now what we want to do in here is to say and we want to create a family we say 5013 06:46:41,218 --> 06:46:46,440 family like this is Mom plus dad so Mom and Dad 5014 06:46:46,440 --> 06:46:50,400 create a family together however this operator at the moment is not defined 5015 06:46:50,400 --> 06:46:55,680 Swift doesn't understand what plus between two persons means so we can go 5016 06:46:55,680 --> 06:47:00,240 ahead and actually Define that so we say we have a function in here we say funk 5017 06:47:00,240 --> 06:47:06,540 Plus on the left hand side we take a person you see a person and right hand 5018 06:47:06,540 --> 06:47:10,138 side another person so we say a left-hand side person 5019 06:47:10,138 --> 06:47:13,798 and we say right hand side person I can understand that we said left hand side 5020 06:47:13,798 --> 06:47:17,100 and right hand side are probably going to be different types and we've so far 5021 06:47:17,100 --> 06:47:20,878 created binary infix operators with the same types for both parameters and we're 5022 06:47:20,878 --> 06:47:23,340 going to do something different now so you're probably asking yourself so why 5023 06:47:23,340 --> 06:47:27,420 aren't we doing something different but before we do that different thing that 5024 06:47:27,420 --> 06:47:30,420 we're going to do we have to first implement this function you'll see soon 5025 06:47:30,420 --> 06:47:35,280 okay so we first say if you create if you add two persons together we create a 5026 06:47:35,280 --> 06:47:40,400 family all right then in here we say we create a family with members equal to 5027 06:47:40,400 --> 06:47:44,458 this let's create these in separate lines like that 5028 06:47:44,458 --> 06:47:48,900 the members are at the left hand side and the right hand side okay now all of 5029 06:47:48,900 --> 06:47:52,860 a sudden you can see this error will go away and then you get a family in here 5030 06:47:52,860 --> 06:47:56,940 okay so that's one thing now what happens if 5031 06:47:56,940 --> 06:48:00,840 you then go ahead and say for instance family 5032 06:48:00,840 --> 06:48:07,558 with sun is equal to family plus some hmm does this work no it won't because 5033 06:48:07,558 --> 06:48:12,000 the left hand side of this operator is a family and the right hand side is a 5034 06:48:12,000 --> 06:48:17,100 person and what we've defined is plus between two persons not a family and a 5035 06:48:17,100 --> 06:48:22,680 person so what we're going to do is to go ahead and say func Plus on the LA on 5036 06:48:22,680 --> 06:48:26,580 the left hand side we're going to take in and we're going to take in a family 5037 06:48:26,580 --> 06:48:31,378 all right so we're gonna say on the left hand side we have family and the right 5038 06:48:31,378 --> 06:48:36,478 hand side we have a person and this returns also a new family then we go 5039 06:48:36,478 --> 06:48:42,058 ahead and we say we take the current families members family members then we 5040 06:48:42,058 --> 06:48:48,058 append to it the current uh the person to the right hand side 5041 06:48:48,058 --> 06:48:52,920 then we create a new family and return it with the given members like this all 5042 06:48:52,920 --> 06:48:55,920 right and then you can then see that this 5043 06:48:55,920 --> 06:49:00,958 error will also go away so you can say family dot members 5044 06:49:00,958 --> 06:49:06,718 dot count and then in here you say family with sun members.com which should 5045 06:49:06,718 --> 06:49:12,240 be one more than this family you can see it's three okay now what if you want to 5046 06:49:12,240 --> 06:49:15,958 say family with daughters so let's say family 5047 06:49:15,958 --> 06:49:20,760 with daughters and then you say okay take the family with the son and then 5048 06:49:20,760 --> 06:49:25,558 add a whole array of daughters to this so you say daughter one and daughter two 5049 06:49:25,558 --> 06:49:29,580 or S sorry not an array of daughters but an array of person you'll get an error 5050 06:49:29,580 --> 06:49:35,100 now because we still don't have an operator that can work on a an object on 5051 06:49:35,100 --> 06:49:38,458 the left hand side of type family and an object on the right hand side of type an 5052 06:49:38,458 --> 06:49:43,558 array of person but we can go ahead and Define that okay so we can say func Plus 5053 06:49:43,558 --> 06:49:48,780 on the left hand side we take a family and the right hand side we take an array 5054 06:49:48,780 --> 06:49:55,020 of persons and this guy returns a family all right so the way to do it is to say 5055 06:49:55,020 --> 06:50:01,080 VAR members again members equal to left hand side members then we 5056 06:50:01,080 --> 06:50:07,620 say members birth append contents of the right hand 5057 06:50:07,620 --> 06:50:13,500 side okay and then we return a family a new family with the new members 5058 06:50:13,500 --> 06:50:18,540 like this all right so now you can see this error will also go away and if you 5059 06:50:18,540 --> 06:50:23,400 say family with daughters dot members dot count then you should get the value 5060 06:50:23,400 --> 06:50:28,978 of five printed to the console in here okay so you can see how easy it is to 5061 06:50:28,978 --> 06:50:32,580 rationalize about how operators should work in Swift they're just simple 5062 06:50:32,580 --> 06:50:38,840 functions except for unaryfx and urinary postfix which you have to also create 5063 06:50:38,840 --> 06:50:44,340 these operator um tags kind of or declarations so this 5064 06:50:44,340 --> 06:50:47,940 is the implementation of the operator and this is the Declaration of the 5065 06:50:47,940 --> 06:50:52,378 operator okay so I think that is actually quite enough right now about 5066 06:50:52,378 --> 06:50:56,580 custom operators in the next section we're going to talk about some of the 5067 06:50:56,580 --> 06:51:02,760 new features uh inside Swift for a basically concurrency and 5068 06:51:02,760 --> 06:51:08,280 asynchronous Swift and that is going to be the last section for this course and 5069 06:51:08,280 --> 06:51:12,600 so without further Ado let's just get started with it I'm going to close this 5070 06:51:12,600 --> 06:51:17,100 tab in here and then I'm going to create a new playground and then let's say 5071 06:51:17,100 --> 06:51:23,040 playground and we call it async Swift all right and 5072 06:51:23,040 --> 06:51:27,420 we just say we want to import foundation and here is one of the exceptions where 5073 06:51:27,420 --> 06:51:31,798 we have to import three things we say import also playground support and then 5074 06:51:31,798 --> 06:51:37,740 we import import concurrency concurrency like this 5075 06:51:37,740 --> 06:51:41,760 and we're doing this playground support here simply because asynchronous code 5076 06:51:41,760 --> 06:51:46,320 requires that our playground is active all the time and it doesn't just start 5077 06:51:46,320 --> 06:51:51,000 from the beginning and ends and when the when it encounters the end of the file 5078 06:51:51,000 --> 06:51:55,200 we just need the playground to stay alive simply because concurrent code and 5079 06:51:55,200 --> 06:52:00,180 and asynchronous code requires that kind of behavior because if you make an API 5080 06:52:00,180 --> 06:52:04,558 call that takes three seconds to finish maybe before that API call is done your 5081 06:52:04,558 --> 06:52:08,040 playground has already reached its and it just terminates and you don't want 5082 06:52:08,040 --> 06:52:14,520 that so let's go and say playground support sir playground page at dot 5083 06:52:14,520 --> 06:52:20,700 currents page and then we say needs indefinite execution equal to true so if 5084 06:52:20,700 --> 06:52:24,478 you're running your code on a Macintosh in xcode then you have to do this but if 5085 06:52:24,478 --> 06:52:27,600 you're on Windows or Linux and you're in Visual Studio code I'm just running your 5086 06:52:27,600 --> 06:52:30,900 code using simple Swift then you shouldn't really do this you should 5087 06:52:30,900 --> 06:52:37,920 perhaps just create a simple project that can have a main Loop and then you 5088 06:52:37,920 --> 06:52:41,940 can then execute your code inside that main Loop That Never Ends okay and 5089 06:52:41,940 --> 06:52:45,900 however if you're in a playground then you will need to do this on Mac OS all 5090 06:52:45,900 --> 06:52:49,138 right now let's say that we want to create a 5091 06:52:49,138 --> 06:52:54,240 simple asynchronous function in Swift if you're already familiar with dart for 5092 06:52:54,240 --> 06:52:58,798 instance for flutter or python or rust you probably have already used Tokyo 5093 06:52:58,798 --> 06:53:04,500 perhaps in rust or in Dart you also have Futures and stream stream controllers 5094 06:53:04,500 --> 06:53:08,458 you're probably already familiar with asynchronous code but if you're not I'll 5095 06:53:08,458 --> 06:53:12,478 just quickly brief you on what it means it means if you have an asynchronous 5096 06:53:12,478 --> 06:53:17,160 function it will not immediately return its result it can take any number of 5097 06:53:17,160 --> 06:53:21,120 seconds or milliseconds to complete its work and return some value and perhaps 5098 06:53:21,120 --> 06:53:24,360 it won't even return a valuesome asynchronous functions don't return a 5099 06:53:24,360 --> 06:53:28,740 value okay so let's go ahead and create a simple dummy function in here which we 5100 06:53:28,740 --> 06:53:34,020 call calculate full name so we say funk calculate full name all right then we 5101 06:53:34,020 --> 06:53:38,100 say we have a first name first name is string and then we have a last name 5102 06:53:38,100 --> 06:53:43,378 which is a string then we say it is an async function which returns a string 5103 06:53:43,378 --> 06:53:47,878 okay so by creating this asynchronous function in here you'll have the ability 5104 06:53:47,878 --> 06:53:52,978 to basically delay the return of your results so you can in here just say 5105 06:53:52,978 --> 06:53:58,138 return hello you could definitely do that but that's not the point of async 5106 06:53:58,138 --> 06:54:02,638 functions this is asynchronous function not an asynchronous function a 5107 06:54:02,638 --> 06:54:06,478 synchronous function returns this value immediately and asynchronous function 5108 06:54:06,478 --> 06:54:10,860 might take some time before it returns its value so let's go ahead and say we 5109 06:54:10,860 --> 06:54:18,120 try to await on a task by sleeping for the duration of one second so this is 5110 06:54:18,120 --> 06:54:22,260 how you would create a delay a fake delay in your function all right and 5111 06:54:22,260 --> 06:54:25,860 we're using the try with question mark syntax in here because we're not 5112 06:54:25,860 --> 06:54:31,440 throwing okay if this function throws then we didn't have to do that 5113 06:54:31,440 --> 06:54:34,920 however we're saying that our function is an async function that doesn't throw 5114 06:54:34,920 --> 06:54:39,298 let's also Mark our playground as automatically running 5115 06:54:39,298 --> 06:54:44,520 so we say try and we say await and let's say cannot convert return expression 5116 06:54:44,520 --> 06:54:49,260 okay and here then we can say return after waiting one second return the 5117 06:54:49,260 --> 06:54:53,638 first name with the space and the last name as the result of this function all 5118 06:54:53,638 --> 06:54:57,420 right that error is now going to go away now inside your playground if you want 5119 06:54:57,420 --> 06:55:01,620 to call this asynchronous asynchronous function you have to create a task and 5120 06:55:01,620 --> 06:55:06,600 then you can say let result 1 is equal to a weight on the result of calculating 5121 06:55:06,600 --> 06:55:12,298 the full name the full name comes from the values of Foo and Bar in here okay 5122 06:55:12,298 --> 06:55:18,660 and you can see the result is actually Foo bar all right it waited before it 5123 06:55:18,660 --> 06:55:23,638 calculated the value for us then we can also go ahead I mean you can see in here 5124 06:55:23,638 --> 06:55:27,600 we have let result equal to a weight but there is another syntax word in Swift 5125 06:55:27,600 --> 06:55:33,240 which is called async let and you can say async let result 2 is calculate and 5126 06:55:33,240 --> 06:55:38,280 so you can see how async is before the let and then we say take Foo bar again 5127 06:55:38,280 --> 06:55:42,600 as the values and in here if you want to if you want to wait for the result of 5128 06:55:42,600 --> 06:55:47,760 this you have to await on it so you say a way to resolve to now asynclet is a 5129 06:55:47,760 --> 06:55:51,058 little bit more special because it creates a child task as part of this 5130 06:55:51,058 --> 06:55:55,200 task you can read about it in Swift Evolution on GitHub and so I won't go 5131 06:55:55,200 --> 06:56:00,180 too much into it but it is kind of similar to this guy uh but it has a 5132 06:56:00,180 --> 06:56:03,540 little bit difference in like how you await on it because some developers 5133 06:56:03,540 --> 06:56:07,740 think maybe that oh this by default awaits on this but it doesn't okay you 5134 06:56:07,740 --> 06:56:12,058 have to wait on the result yourself manually okay so that's how you can 5135 06:56:12,058 --> 06:56:16,440 create a simple task in asynchronous task and then do some async and a weight 5136 06:56:16,440 --> 06:56:21,000 code inside it in Swift now we can go ahead and put together 5137 06:56:21,000 --> 06:56:25,260 maybe an example that talks about async and async let's and tasks all together 5138 06:56:25,260 --> 06:56:32,700 just to make it stick a little bit more okay so let's say we create a cloth enum 5139 06:56:32,700 --> 06:56:38,580 in here and we say we have case socks we have shirts and trousers all right then 5140 06:56:38,580 --> 06:56:41,940 let's create some asynchronous functions in here so we say the first function 5141 06:56:41,940 --> 06:56:47,820 that we have is called buy socks all right and it is an async function that 5142 06:56:47,820 --> 06:56:53,218 throws and we say it returns a clove and what it does is it says try a weight 5143 06:56:53,218 --> 06:56:58,740 on a task by sleeping for a duration of one second and the reason this function 5144 06:56:58,740 --> 06:57:02,878 throws is that we're not doing try like this if we did try with a question mark 5145 06:57:02,878 --> 06:57:07,020 we didn't have to throw okay but we're doing just normal try therefore the 5146 06:57:07,020 --> 06:57:11,400 function has to throw or it has to be inside I do but what we're indicating to 5147 06:57:11,400 --> 06:57:13,860 the outside world by writing this function and seeing that this function 5148 06:57:13,860 --> 06:57:16,978 is an asynchronous function that can internally actually throw an error so be 5149 06:57:16,978 --> 06:57:21,660 careful while consuming its value all right then we return a close of type 5150 06:57:21,660 --> 06:57:26,340 socks so after one second we produce an item of clothing 5151 06:57:26,340 --> 06:57:31,200 after doing this one we can go ahead and create another function which is called 5152 06:57:31,200 --> 06:57:37,020 by shirt like this and it produces an item of clothing and ins in here we just 5153 06:57:37,020 --> 06:57:42,240 say shirt all right and we can create another one that produces a item of 5154 06:57:42,240 --> 06:57:49,020 trousers so we say trousers and it says dot trousers all right so they're very 5155 06:57:49,020 --> 06:57:53,820 similar to each other they just return a different result of them now you want to 5156 06:57:53,820 --> 06:58:00,000 create a structure in here that is an ensemble an ensemble is a you can say it 5157 06:58:00,000 --> 06:58:05,700 is a collection of clothing clothes items and you can say struct Ensemble 5158 06:58:05,700 --> 06:58:11,458 all right and then we say this guy has clothes in it and we say it is an array 5159 06:58:11,458 --> 06:58:16,558 of clothes and it has a total price price of type double all right doesn't 5160 06:58:16,558 --> 06:58:20,638 really matter what the currency for the prices we also want this Ensemble to be 5161 06:58:20,638 --> 06:58:25,500 printable to the console in a very nice format so we can form it to custom debug 5162 06:58:25,500 --> 06:58:29,280 string convertible protocol and therefore we have to implement a new 5163 06:58:29,280 --> 06:58:35,280 variable here called debug description like this we make it a computed property 5164 06:58:35,280 --> 06:58:41,700 and then we say clothes equal to clothes and we say price is equal to total price 5165 06:58:41,700 --> 06:58:45,298 so the value that you're producing here will then be printed to the debug 5166 06:58:45,298 --> 06:58:50,878 console whenever you try to debug an instance of this Ensemble structure okay 5167 06:58:50,878 --> 06:58:56,638 now we create a function in here called by whole ensemble 5168 06:58:56,638 --> 06:59:00,780 like this and we say it it's an async function that throws and it produces an 5169 06:59:00,780 --> 06:59:06,600 ensemble in here okay then we should go ahead and buy all our uh parts so we say 5170 06:59:06,600 --> 06:59:15,240 async LED socks is buy socks async let shirt is by shirt and async lets 5171 06:59:15,240 --> 06:59:21,298 trousers is by trousers all right so since all these are async let's then we 5172 06:59:21,298 --> 06:59:26,160 need to await on them and also we should also sorry not also also twice now 5173 06:59:26,160 --> 06:59:29,940 became four times so what we want to do is to go and 5174 06:59:29,940 --> 06:59:35,520 create an ensemble so we say let's Ensemble on uh symbol is an instance of 5175 06:59:35,520 --> 06:59:39,240 Ensemble and it says okay give me the clothes and you probably think okay I'm 5176 06:59:39,240 --> 06:59:42,180 just gonna give it socks shirt and trousers but you can't do that because 5177 06:59:42,180 --> 06:59:47,040 these are async let's items you have to await on them so just type a weight and 5178 06:59:47,040 --> 06:59:52,440 then we go ahead in here we say socks a shirt trousers but since these guys are 5179 06:59:52,440 --> 06:59:57,798 also throwing functions you have to try them okay so you say try try try 5180 06:59:57,798 --> 07:00:03,540 and then for the total price we're gonna say the total price is 200 okay 5181 07:00:03,540 --> 07:00:07,558 there we go and then we can return The Ensemble like this now all these errors 5182 07:00:07,558 --> 07:00:11,700 are hopefully gonna go away so there we go 5183 07:00:11,700 --> 07:00:15,600 now you can to test this you create a task in your playground and then you can 5184 07:00:15,600 --> 07:00:21,298 say a flat Ensemble is equal to try a weight on buy 5185 07:00:21,298 --> 07:00:27,900 hola Ensemble then you can say Ensemble is this otherwise something went wrong 5186 07:00:27,900 --> 07:00:33,298 like that all right and then you can see our Ensemble debug description will be 5187 07:00:33,298 --> 07:00:37,378 printed to the screen says clothes are this let's see if you can get the entire 5188 07:00:37,378 --> 07:00:41,160 clothes maybe we could print it even so print 5189 07:00:41,160 --> 07:00:44,400 it's a little bit easier perhaps to read it here 5190 07:00:44,400 --> 07:00:50,760 there we go so it says is a shirt it's a socks trousers and also the price is 200 5191 07:00:50,760 --> 07:00:56,638 dollars let's say okay now async lab can only be used within asynchronous 5192 07:00:56,638 --> 07:01:01,798 closures and asynchronous functions or wherever there is a task being run so 5193 07:01:01,798 --> 07:01:07,680 you cannot use asynchronous async let within uh anything that is not one of 5194 07:01:07,680 --> 07:01:11,820 the ones that I just described so it should be an asynchronous closure an 5195 07:01:11,820 --> 07:01:17,040 asynchronous function or wherever there is a task that you have such as in here 5196 07:01:17,040 --> 07:01:22,020 okay so let's let's have a look at a few examples we go in here and we just say 5197 07:01:22,020 --> 07:01:27,780 funk get full name and we ask for a delay a fake delay and we say it's of 5198 07:01:27,780 --> 07:01:31,620 type duration and we say we have a calculator for 5199 07:01:31,620 --> 07:01:36,180 what we calculate like how we calculate the full name and it is an async 5200 07:01:36,180 --> 07:01:41,940 function that returns a string in here and then we say it is async 5201 07:01:41,940 --> 07:01:47,820 function add it in itself returns a string so our job is just to try to 5202 07:01:47,820 --> 07:01:55,378 await on this uh task sleep for this delay and then we return and we want to 5203 07:01:55,378 --> 07:01:59,400 return the result of this function but it is an async function so we have to 5204 07:01:59,400 --> 07:02:04,260 await on it so we say wait on the calculator like this all right and then 5205 07:02:04,260 --> 07:02:07,680 you can see all these errors are then going to go away and then we have our 5206 07:02:07,680 --> 07:02:10,440 print statement in here let's just remove it so that we don't get this 5207 07:02:10,440 --> 07:02:15,058 print in the console all right now that we have that we can go ahead 5208 07:02:15,058 --> 07:02:19,740 and actually say we have a funk and we call it full name and we say it's an 5209 07:02:19,740 --> 07:02:24,718 async function which is an error function and we just for now just we say 5210 07:02:24,718 --> 07:02:28,740 Foo bar all right so it is an async function but right now it just returns 5211 07:02:28,740 --> 07:02:34,500 asynchronous result back to us full name like this then we can create a task and 5212 07:02:34,500 --> 07:02:41,280 we can say await on get full name and we say uh let's break these down and then 5213 07:02:41,280 --> 07:02:47,820 we say the delay is in delay in seconds one and its calculator is indeed uh 5214 07:02:47,820 --> 07:02:53,580 let's actually see for the calculator let's create a a trail enclosure in here 5215 07:02:53,580 --> 07:02:59,820 then we say async let name is full name and then we can say return awaits name 5216 07:02:59,820 --> 07:03:04,440 all right so let's see if we get the results printed to the screen now you 5217 07:03:04,440 --> 07:03:09,600 can see Fubar then being printed to the screen so we could use async let simply 5218 07:03:09,600 --> 07:03:15,360 because we're in a an async trailing closure okay and also we've been able to 5219 07:03:15,360 --> 07:03:20,580 use asynclet in other contexts such as here which we're in an async function 5220 07:03:20,580 --> 07:03:24,780 all right so I mean there's a lot more actually to 5221 07:03:24,780 --> 07:03:30,420 talk about when it comes to asynchronous programming with swift but this just 5222 07:03:30,420 --> 07:03:35,160 gives you an idea of the basics of asynchronous programs very similar to 5223 07:03:35,160 --> 07:03:38,040 JavaScript and typescript and you could also say it's very similar to actually 5224 07:03:38,040 --> 07:03:42,718 Dart for instance for those of you who do flutter development it's a little bit 5225 07:03:42,718 --> 07:03:48,540 more complicated because well it is Swift it has a long history of its own 5226 07:03:48,540 --> 07:03:52,500 code base and there are a lot of people contributing to Swift as a programmable 5227 07:03:52,500 --> 07:03:58,558 language not even just people just inside Apple so it is somehow a mishmash 5228 07:03:58,558 --> 07:04:02,400 of everything the community thought was a good idea to add to Swift I personally 5229 07:04:02,400 --> 07:04:06,660 don't like for instance async let I think it makes things more complicated 5230 07:04:06,660 --> 07:04:10,378 almost every other program language that has asynchronous programming such as 5231 07:04:10,378 --> 07:04:14,820 JavaScript typescript and dart don't need async lab they just do async and a 5232 07:04:14,820 --> 07:04:19,020 weight and everything works as expected I think async lab adds a new layer of 5233 07:04:19,020 --> 07:04:21,600 complexity to your code which is unnecessary 5234 07:04:21,600 --> 07:04:24,900 some people may argue that it is actually nice but I personally don't 5235 07:04:24,900 --> 07:04:29,878 like it so much but that's just my opinion and I think it although I don't 5236 07:04:29,878 --> 07:04:34,920 like it so much I learn it and I think it is important that we all learn how to 5237 07:04:34,920 --> 07:04:39,660 use these syntaxes that are available in modern Swift so with that said I think 5238 07:04:39,660 --> 07:04:44,160 we can then conclude this particular video of the full stack with swift 5239 07:04:44,160 --> 07:04:50,218 course and we've talked a lot about you can see we have so many playgrounds in 5240 07:04:50,218 --> 07:04:53,040 here I can't even count but we talk about variables operators classes 5241 07:04:53,040 --> 07:04:58,320 expenses generics pretty much everything that you can think of in Swift so now 5242 07:04:58,320 --> 07:05:02,280 what we're gonna do in the course is to go ahead and start talking about client 5243 07:05:02,280 --> 07:05:06,000 development and also back-end development with Swift I really hope 5244 07:05:06,000 --> 07:05:09,780 that you enjoyed this video if you found it helpful please press the thanks 5245 07:05:09,780 --> 07:05:13,500 button at the bottom of the screen or you can just alternatively join my 5246 07:05:13,500 --> 07:05:17,958 YouTube channel so see you in the next video841320

Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.