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

af Afrikaans
ak Akan
sq Albanian
am Amharic
ar Arabic
hy Armenian
az Azerbaijani
eu Basque
be Belarusian
bem Bemba
bn Bengali
bh Bihari
bs Bosnian
br Breton
bg Bulgarian
km Cambodian
ca Catalan
ceb Cebuano
chr Cherokee
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
ee Ewe
fo Faroese
tl Filipino
fi Finnish
fr French
fy Frisian
gaa Ga
gl Galician
ka Georgian
de German
el Greek
gn Guarani
gu Gujarati
ht Haitian Creole
ha Hausa
haw Hawaiian
iw Hebrew
hi Hindi
hmn Hmong
hu Hungarian
is Icelandic
ig Igbo
id Indonesian
ia Interlingua
ga Irish
it Italian
ja Japanese
jw Javanese
kn Kannada
kk Kazakh
rw Kinyarwanda
rn Kirundi
kg Kongo
ko Korean
kri Krio (Sierra Leone)
ku Kurdish
ckb Kurdish (Soranî)
ky Kyrgyz
lo Laothian
la Latin
lv Latvian
ln Lingala
lt Lithuanian
loz Lozi
lg Luganda
ach Luo
lb Luxembourgish
mk Macedonian
mg Malagasy
ms Malay
ml Malayalam
mt Maltese
mi Maori
mr Marathi
mfe Mauritian Creole
mo Moldavian
mn Mongolian
my Myanmar (Burmese)
sr-ME Montenegrin
ne Nepali
pcm Nigerian Pidgin
nso Northern Sotho
no Norwegian
nn Norwegian (Nynorsk)
oc Occitan
or Oriya
om Oromo
ps Pashto
fa Persian
pl Polish
pt-BR Portuguese (Brazil)
pt Portuguese (Portugal)
pa Punjabi
qu Quechua
ro Romanian
rm Romansh
nyn Runyakitara
ru Russian
sm Samoan
gd Scots Gaelic
sr Serbian
sh Serbo-Croatian
st Sesotho
tn Setswana
crs Seychellois Creole
sn Shona
sd Sindhi
si Sinhalese
sk Slovak
sl Slovenian
so Somali
es Spanish
es-419 Spanish (Latin American)
su Sundanese
sw Swahili
sv Swedish
tg Tajik
ta Tamil
tt Tatar
te Telugu
th Thai
ti Tigrinya
to Tonga
lua Tshiluba
tum Tumbuka
tr Turkish
tk Turkmen
tw Twi
ug Uighur
uk Ukrainian
ur Urdu
uz Uzbek
vi Vietnamese Download
cy Welsh
wo Wolof
xh Xhosa
yi Yiddish
yo Yoruba
zu Zulu

Original subtitles

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

đượ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

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

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

í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

đá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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

đ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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

đó 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

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

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

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

đủ ở đâ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

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

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

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

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

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

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

tài liệu và ở đây gõ sân chơi vào file and in here type playground in the

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

đượ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

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

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

để 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

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

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

nước ngoài foreign

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

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

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

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

ừ, 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

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

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

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

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

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

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

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

được giao lại và còn một số nhỏ khác be assigned to again and there are some other small

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

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

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

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

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

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

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

đã 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

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

ở 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

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

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

đượ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

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

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

để 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

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

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

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

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

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

đượ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

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

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

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

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

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

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

để 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

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

đ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

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

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

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

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

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

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

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

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

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

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

đặ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

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

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

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

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

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

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

đấ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

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

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

để 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

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

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

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

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

đượ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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

đượ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

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

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

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

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

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

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

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

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

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

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

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

đố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

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

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

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

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

â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

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

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

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

ả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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

để 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

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

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

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

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

ở đâ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

đó 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

đã 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

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

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

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

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

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

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

đượ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

đó 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

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

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

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

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

vì mảng mới có giá trị cũ mảng since new array got the value of old array

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

đ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

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

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

để 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

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

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

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

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

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

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

đượ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

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

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

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

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

ừ 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

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

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

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

ừ 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

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

đượ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

đã đượ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

để 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

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

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

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

đó 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

đ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

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

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

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

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

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

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

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

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

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

đẹ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

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

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

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

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

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

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

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

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

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

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

đặ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

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

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

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

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

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

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

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

đ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

để 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

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

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

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

Về toán tử vì vậy hãy tạo hai hằng số about operators so let's create two constants

ở đâ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

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

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

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

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

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

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

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

đã 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

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

ở đâ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

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

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

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

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

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

đú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

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

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

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

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

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

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

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

đã 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

ở 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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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.

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

đượ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

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

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

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

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

đơ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

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

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

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

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

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

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

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

ở 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

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

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

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

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

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

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

để 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

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

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

ở đâ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

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

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

ý 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

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

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

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

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

đ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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

ở 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

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

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

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

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

ừm trung tố nhị phân um infix binary

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

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

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

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

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

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

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

đượ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

đượ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

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

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

đượ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

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

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

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

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

ừ 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

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

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

là những gì ừ ranh giới mà họ là gì what are the um what are the boundaries that they

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

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

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

đượ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

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

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

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

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

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

được rồi ừ và sau đó bạn có thể nói nếu okay uh and then you could say if

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

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

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

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

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

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

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

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

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

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

được rồi và sau đó định dạng là bạn đặt một okay and then the format is then you put a

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

đượ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

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

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

ở đâ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

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

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

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

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

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

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

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

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

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

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

đế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

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

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

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

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

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

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

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

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

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

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

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

Tốt tiếc là không giống một số người khác well unfortunately unlike some other

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

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

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

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

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

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

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

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

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

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

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

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

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

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

sân chơi và hãy gọi nó nếu playground and let's just call it if

khác và vui lòng đảm bảo rằng bạn không else and please just ensure that you're not

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

ở đâ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

đ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

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

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

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

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

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

ồ 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

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

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

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

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

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

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

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

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

đồ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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

ừ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

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

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

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

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

đ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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

độ 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

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

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

đừ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

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

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

để 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

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

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

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

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

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

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

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

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

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

đ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

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

đã 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

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

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

đượ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

ở đâ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

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

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

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

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

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

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

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

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

đó 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

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

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

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

đ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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

ở đâ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

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

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

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

điều này được rồi Vì thế this okay so

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

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

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

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

không đúng, để tôi chỉ cho bạn xem ví dụ incorrect let me just show you an example

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

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.

đượ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

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

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

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

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

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

ngu hoặc Foo or

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

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

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

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

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

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

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.

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

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

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

đã 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

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

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

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

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

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

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

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

ư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

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

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

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

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

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

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

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

đ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

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

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

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

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

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

tên bạn là Foo your name is Foo

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

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

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

đ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

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

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

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

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

ồ 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

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

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

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

đặ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

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

đượ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

đơ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

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

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

đơ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

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

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

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

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

đô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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

để đ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

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

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

đượ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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

đượ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

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

đượ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

ở đâ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

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

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

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

đượ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

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

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

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

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

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

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

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

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

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

đố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

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

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

nhãn và nhãn nội bộ thứ gì đó label and an internal label which is something

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

đâ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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

ở đâ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

đượ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

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

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

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

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

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

ở đâ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

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

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

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

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

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

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

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

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

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

đượ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

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

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

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

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

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

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

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

đượ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

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

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

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

đượ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

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

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

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

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

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

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

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

để đả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

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

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

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

đượ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

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

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

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

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

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

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

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

đ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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

ở đâ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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

đâ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

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

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

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

đế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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

ở đâ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

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

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

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

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

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

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

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

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

ở đâ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

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

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

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

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

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

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

ở đâ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

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

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

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

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

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

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

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

đượ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

ở đâ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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

ở đâ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

ừ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

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

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

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

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

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

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

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

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

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

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

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

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

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

đó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

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

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

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

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

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

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

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

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

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

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

ở đâ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

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

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

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

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

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

cạnh cộng với vế phải là thế chức năng side plus right hand side is that function

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

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

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

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

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

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

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

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

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

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

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

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

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

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

được rồi và bạn trả về một số nguyên okay and you return an integer

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

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

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

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

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

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

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

đượ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

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

đố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

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

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

đượ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

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

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

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

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

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

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

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

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

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

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

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

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

ở đâ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

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

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

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

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

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

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

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

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

ở đâ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

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

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

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

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

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

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

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

đặ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

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

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

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

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

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

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

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

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

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

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

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

đặ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

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

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

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

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

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

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

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

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

đế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

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

độ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

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

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

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

đố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

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

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

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

đượ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

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

đú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

đó 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

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

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

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

đố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

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

ở đâ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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

đú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

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

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

đế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

ừ, 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

đú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

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

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

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

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

đã 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

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

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

mã số trung bình có lẽ được viết trong đó tôi code on average perhaps written in them I've

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

đ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

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

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

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

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

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

đố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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

đ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

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

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

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

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

đượ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

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

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

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

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

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

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

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

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

đượ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

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

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

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

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

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

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

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

đượ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

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

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

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

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

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

đã 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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

ừm toán tử là một trung tố nhị phân um operator which is a binary infix

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

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

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

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

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

đ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

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

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

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

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

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

cái này đúng bởi vì nó giống nhau this right because it is the same thing it is

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

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

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

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

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

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

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

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

ở đâ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

Vì thế đó là một ví dụ hay đúng hơn là so that was uh one one example or rather

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

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

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

ở đâ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

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

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

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

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

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

đượ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

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

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

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

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

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

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

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

nói LHS và rhs say LHS and rhs

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

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

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

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

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

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

ở đâ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

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

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

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

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

ừ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

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

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

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

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

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

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

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

đượ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

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

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

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

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

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

đượ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

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

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

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

ở đâ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

để 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

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

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

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

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

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

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

đượ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

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

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

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

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

ừ 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

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

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

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

đượ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

đượ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

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

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

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

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

để 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

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

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

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

ở đâ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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

ừ, 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

Ý 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

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

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

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

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

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

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

ở đâ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

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

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

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

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

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

ở đâ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

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

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

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

để 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

đượ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

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

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

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

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

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

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

đó 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

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

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

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

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

ở đâ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

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

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

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

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

đượ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

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

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

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

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

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

đơ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

đượ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

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

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

đượ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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

đó 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

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

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

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

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

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

đ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

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

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

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

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

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

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

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

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

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

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

ở đâ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

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

như thế này được rồi, điều này sẽ đạt được like this okay so this would have achieved the

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

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

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

đượ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

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

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

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

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

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

đ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

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

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

logic kinh doanh yêu cầu bạn làm điều đó được rồi business logic requires you to do that okay

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

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

ừ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

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

ở đâ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

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

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

ở đâ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

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

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

đố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

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

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

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

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

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

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

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

đâ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

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

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

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

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

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

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

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

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

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

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

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

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

đã 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

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

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

phải nói trước VAR Xác định dữ liệu kiểu have to say first VAR Define the data type

để 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

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

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

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

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

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

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

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

được rồi Hiện nay all right now

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

độ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

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

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

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

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

ồ 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

đú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

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

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

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

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

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

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

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

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

đượ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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

đ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

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

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

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

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

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

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

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

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

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

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

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

Ý 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

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

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

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

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

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.

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

như thế này và lái xe với tốc độ 30. like this and drive with the speed of 30.

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

Sẽ đổi thành 30 ở đây nhé Vì thế is Gonna Change to 30 in here okay so

ừ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

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

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

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

ở đâ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

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

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

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

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

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

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

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

ở 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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

hiểu về cấu trúc Vì thế understand about structures so

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

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

ở đâ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

đã đề 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

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

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

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

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

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

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

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

đ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

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

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

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

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

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

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

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

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

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

để 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

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

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

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

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

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

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

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

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

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

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

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

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

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

đú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

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

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

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

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

đơ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

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

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

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

ở đâ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

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

đượ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

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

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

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

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

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

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

đượ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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

đượ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

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

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

để 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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

độ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

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

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

ở đâ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

hoặc gõ là Doc hoặc gõ or type is Doc or type

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

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

đó 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

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

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

đây và đó là lý do chúng tôi có here and that is the reason we have

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

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

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

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

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

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

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

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

đâ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

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

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

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

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

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

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

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

đ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

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

độ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

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

đố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

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

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

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

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

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

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

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

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

đâ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

độ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

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

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

đế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

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

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

ồ 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

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

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

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

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

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

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

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

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

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

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

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

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

đơ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

một ví dụ về động vật khá ngang bằng mèo ổn an instance of animals rather equal to cat okay

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

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

độ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

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

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

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

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

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

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

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

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

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

đượ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

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

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

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

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

để 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

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

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

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

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

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

đú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

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

ồ 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

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

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

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

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

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

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

ừ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

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

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

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

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

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

ừ độ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

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

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

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

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

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

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

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

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

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

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

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

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

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

đả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

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

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

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

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

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

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

ồ 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

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

ở đâ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

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

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

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

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

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

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

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

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

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

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

đ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

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

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

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

tích hợp được gọi là phím tắt hoặc phím tắt integration called shortcuts or shortcuts

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

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

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

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

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

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

www.táo là phím tắt www.apple is shortcut

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

đượ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

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

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

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

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

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

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

đườ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

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

đườ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

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

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

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

đượ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

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

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

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

đã 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

đố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

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

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

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

được rồi bây giờ bạn sẽ nghĩ ổn thôi okay now you would be thinking okay now that

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

ứ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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

đ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

ở đâ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

ở đâ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

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

đượ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

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

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

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

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

nghệ sĩ rồi in tên bài hát rồi artist and then print the song name and then

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

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

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

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

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

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

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

đườ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

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

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

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

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

ở đâ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

đ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

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

đ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

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

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

những cái này hãy được rồi vậy hãy để these let's okay so that let

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

tiếp tục ngay sau loại trường hợp cho phép to go ahead right after the case type let

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

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

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

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

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

trong các lần lặp có liên kết giá trị in iterations that have Associated values

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

đ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

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

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

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

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

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

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

đó 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

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

ở đâ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

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

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

đơ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

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

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

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

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

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

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

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

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

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

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

để 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

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

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

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

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

đượ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

ở đâ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

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

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

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

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

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

đượ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

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

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

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

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

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

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

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

đố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

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

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

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

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

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

ồ 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

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

đượ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

ở đâ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

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

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

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

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

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

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

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

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

đượ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

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

ngoài chuyện này thì tôi sẽ nói vui ừm out of this then I will say funk um

có được nhà sản xuất từ xe get manufacturer from vehicle

đượ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

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

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

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

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

đ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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

cái này và loại bỏ trường hợp này this and remove this case

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

vậy hãy tiếp tục và nói enum gia đình that so let's go ahead and say enum family

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

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

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

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

bố là vậy đó mẹ là mẹ father is that mother is Mom

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

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

đâ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

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

đú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

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

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

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

đang định nói anh bạn ở đây được rồi going to say bro in here okay

ừ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

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

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

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

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

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

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

đủ 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

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

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

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

đượ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

đây sau đó chúng tôi nói trường hợp cháy là here we then say case fire is

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

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

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

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

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

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

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

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

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

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

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

đượ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

Ý 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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

độ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

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

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

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

đượ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

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

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

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

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

ở đâ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

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

đơ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

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

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

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

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

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

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

ý 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

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

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

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

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

ở đâ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

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

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

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

đị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

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

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

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

đ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

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

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

đã 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

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

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

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

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

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

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

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

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

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

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

để 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

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

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

ừ đượ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

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

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

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

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

đệ 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

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

đ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

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

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

đượ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

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

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

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

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

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

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

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

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

ý 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

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

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

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

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

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

đã 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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

đượ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

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

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

lỗi này ừm vì this error um because

ừ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

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

ở đâ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

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

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

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

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

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

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

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

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

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

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

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

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

gợi ý nhỏ ở đây và yêu cầu nó có lẽ little hint in here and ask it to perhaps

ô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

để 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

để 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

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

ở 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

ở đâ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

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

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

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

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

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

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

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

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

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

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

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

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

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

sẽ tiếp tục và tự nói rằng đó là tên going to go ahead and say self that's name

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

bằng H được rồi, đó là điều đơn giản equal to H alright so that's that's the simple

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

ở đâ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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

đặ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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

đượ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

như nhau ví dụ về người trong bộ nhớ để thanh được same instance of person in memory so bar gets

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

đơ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

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

đ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

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

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

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

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

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

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

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

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

đâ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

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

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

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

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

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

đã 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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

đó 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

đá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

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

đượ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

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

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

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

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

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

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

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

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

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

đơ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

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

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

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

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

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

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

tại đây được rồi, đó là Cú pháp cho at this all right so that's the Syntax for

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

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

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

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

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

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

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

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

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

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

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

ủ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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

đ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

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

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

ừ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

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

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

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

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

đâ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

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

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.

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

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

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

self.year là một năm được rồi self.year is a year all right

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

không thể giao phó công việc của họ cho người khác cannot delegate their work to another

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

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

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

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

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

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

để 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

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

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

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

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

đượ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

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

đượ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

Tesla mô hình y được rồi và nó đang phân lớp Tesla model y all right and it is subclassing

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

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

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

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

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

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

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

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

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

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

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

đượ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

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

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

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

đã đượ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

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

ở đâ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

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

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

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

gọi tới bộ khởi tạo được chỉ định trong siêu lớp call to designated initializers in their superclass

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

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

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

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

đặ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

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

đô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

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

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

đã 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

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

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

đượ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

đầ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

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

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

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

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

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

đú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

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

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

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

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

đằ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

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

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

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

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

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

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

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

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

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

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

90 percent of ties are working with classes you don't need the initializers

unless you're working with some sort of notifications or RX for instance and

yeah if you're working with reactive programming

so let's have a look at the initializers as their name indicates they're kind of

similar to initializers but they do the opposite the initializers are invoked

automatically by Swift whenever your class instance is going out of memory so

it's kind of getting cleaned from the memory so no one else is holding on to

it and it has to be removed from memory so let's create a my class in here okay

then in the init and we will just say initialized and then we'll have a

function here called do something which which is empty at the moment all right

then we create a new function in here called D in it and you can see that it

is purple in here but it doesn't matter I mean the color doesn't really matter

it just matters that this is a reserved word it's a keyword in Swift meaning

that you can't really use it anywhere else except if you do something like

funky like that but just know that there's a reserved word it's it's

similar to in it but it's just called when your class is going out of scope

and in here we can say d initialized all right now to test this we should

actually create a function in which we create an instance of this because if

you create an instance of your class in here let's just say let's my class is an

instance of my class and then my class do something where the initializer won't

probably be invoked you can see your initializer is invoked uh do something I

mean in here we could actually say do something just so that we see that that

function is also invoked however Danish Lancer isn't embodian that's just the

nature of uh of playgrounds so what you could do is to create a closure my

closure and we say it is this it is basically carrying out this

logic inside the closure and then we can call our closure so at the end of this

closure this variable should go out of scope meaning that it's the initializer

should be called so let's say my closure in here all right and then you can see

your D initializer oopsie Daisy what happened my closure

uh all right cannot find my did I spell it incorrectly like this

and now you can see that the initializer is in fact called and invoked simply

because after my closure is called this scope completely finishes meaning that

all variables inside this scope should also go out of scope so dnits will be

called on all class instances all right really good we seem to now be done

actually with classes so um let's just jump right ahead into the

next concept and that is protocols so I'm going to go in here and actually not

there we don't have to go there I'm just going to press command n in here create

a new playground and we're going to say protocols again ensure that it is inside

your workspace and in not inside another playground

create all right and we get rid of this Explorer in here and we say Foundation

like this Foundation all right now protocols for those of you who are rust

developers you probably already know what protocols are and Protocols are

special kind of objects kind of like interfaces you could say in Java for

instance I'm not sure the term in kotlin what that is but you also have protocols

as mixings in Dart for instance so what protocols are is that you create

an interface you create a set of rules that objects which conform to a protocol

have to follow so it is not a class and because if you

have a class for instance if you have a super class that has some functions all

subclasses do not have to re-implement that function however if you have a

protocol that only creates some functions with no body so the functions

don't have logic in them any object that conforms to those protocols have to

implement those functions by themselves all right so it is actually a little bit

difficult to explain what protocols are without having a look at how they work

so let's go in here and say that this is automatically running and create our

first protocol so we create a protocol called can breathe okay

and in here we say any object that can breathe should have a function called

breathe so you can see this function is special functioning it has no body you

cannot create for instance a class person and just have this in it this

just won't work you have to have a function body and you can't do that

either in structures your function has to have a body so you can see that won't

work in structures either that's why Protocols are a little bit special in

that they can have just function declarations without any implementation

all right and that's what is called interface insomni in so many other

languages all right so we have a protocol now can breathe

let's go ahead and create a structure called animal and we saw when we when we

were talking about structures that structures cannot have super classes so

they cannot actually inherit from each other okay so if you create for instance

a structure of animal and then you say struct cat you cannot say that cat is an

animal it just won't work structures don't allow inheritance however they do

allow inheritance from protocols so you can say a structure of animal that

inherits from can breathe and this is completely fine Swift syntax however

we're getting an error because now you can see it says the animal a type

doesn't conform to protocol can't breathe and the reason behind that is

that a protocol here called can't breathe specifies that anyone conforming

to this protocol has to implement this particular function and we haven't done

that so as soon as we go and type breathing here you can see then this

error will go away because now animal uh character conforms to Cambridge protocol

okay and in here we can just say animal breathing like this okay

and also then you can create another structure struct person can breathe like

this and in here we say breathe as well and then we say person breathing like

that all right so then you can go ahead and create instances of these two

structures we say dog is an animal and we say dog breathe and then we create a

person called Foo an instance of person we say the food breathe all right now

you can see both of these lines will then be invoked uh simply because we

call them from here so that's basically the essence of how protocols work I mean

protocols can be a lot more complicated than that actually uh in that I mean we

talked right now about having protocols that only have function declarations but

not implementations but protocols and Swift are kind of like mix-ins and dart

in that they can't actually have their own implementations so they're not just

like objects that have dummy function headers but they can indeed have

function implementations so let's have a look at that let's create a protocol

called protocol can jump and then we say a jump function all right then in order

to create implementation for this function I mean you may be thinking okay

maybe I should do this jumping and this will just give you an error because you

cannot create your function body inside the Proto call itself the trick to do

that is to go ahead and create an extension on can jump okay and we

haven't talked about extensions yet but it is necessary that we just name it in

here simply because that's the way to actually add implementation to this

function all right then we go and say okay it's the same function and then we

just say jumping so by this trick you I mean it's not

really a trick this is the way to do it by using this uh technique I'm trying to

avoid saying trick by using this technique you're adding a default

implementation to this otherwise very dumb function

so you may be asking okay but what happened here can I just call this

function now so can I just say can jump is an instance of can jump can I do that

well you can't because you cannot instantiate a protocol you need to

instantiate an object that conforms the protocol

okay such as a cat that can jump so let's say struct cat and jump and now

since this jump function already has an implementation you can see that we're

not getting an error from Swift saying cats should implement this function if

you remove this implementation from here all of a sudden all objects that conform

to can jump need to implement this jump function themselves but if you bring it

back into can jump then all objects that conform to that protocol will get this

implementation by default but they can go ahead and change it if they want to

like this okay so that's also valid however if you

leave it it also works with that problem so let's create an instance of this cat

we say Whiskers Whiskers it's an instance of cat and we can just say

whiskers.jump all right this is how we can invoke that function that is

implemented on can jump right now protocols apart from defining

function headers that they're conforming objects have to implement they can also

Define variables let's let's go ahead in here and say we have a protocol in here

we say protocol has name protocol has a name and then in here we say VAR

name a string and then we have to say gets in here or set or both like this

now what this really means is that this protocol is asking Swift saying any

object that com conforms to me has to have a variable called name that has to

at least have a getter what does this mean well this is really just a dumb way

of saying this so it it basically says a variable that

at least I can read from but this syntax isn't valid and protocols I wish it was

but you have to implement them like this so you're basically saying a some sort

of a variable that I can read from which is called name all right and then you

can also have H all right and let's just say h should be getter and Setter

meaning that it should actually be a variable that can be set all right now

we can go ahead in here and say we have a struct of dog and it has a name you

can now see that we'll get an error now from Swift saying that this doesn't

conform to has name and we can ask it to fix it for us and you can see by default

it creates these variables for us however what I really don't like about

this is that what it did is that it created a variable for name so it could

actually be a let since the protocol has name asks for this variable to be at

least and at most actually in read-only so we can just demote this to a let's

variable and you'll see that everything will work as expected okay so let's go

ahead in here and then create an instance of this dog

and we can call this instance woof let's say woof is an instance of dark and we

say name is with an H is a very graceful ten then we say

with that name all right and with that H wolf dot h plus equal one so we just

increase the age but we cannot change the name all right so let's just woof

agent here as well so let's see what happens okay and this I mean we're

getting these errors right here because we can't modify woof because it's an

instance of a structure which by default becomes a left constant that cannot even

have a mutation internally so we have to change this to A4 so remember structures

are different from classes all right so this is basically a protocol that

required all its uh classes or structures that conform to it to have a

variable call name that can at least and at most be read from so it can be a let

and it can also be a VAR but why does it have to be a VAR a promotion of let if

we don't have to have it as a bar because the protocol says I should just

be able to get from it now you may be thinking okay but why do we do these

things well the reason is if you want to go ahead and add functionality to this

protocol then this protocol internally has access to name and age let's say

extension has name and then we can then create a function that says describe me

then we can see we can say you your name is name and you are

age years old okay so since this protocol expects a

name variable and an age variable and it can then go ahead and read them so it

can access them and it should also be able to set them okay and then you can

say func increase age and in here then you can say self h plus equal one and we

can fix this actually now so you can basically go ahead and add

functionality to your protocols let's say fix it and we add a mutating

function in here so you can see this protocol since it knows what it requires

all its uh classes and structures that conform to it have to have these values

then it can go ahead and take advantage of those variables or functions or

whatever it has okay so now all of a sudden all objects are conformed to have

has the name protocol will get a describe me function let's go ahead in

here and say woof you can see it has a describe me function all of a sudden and

it will say oops okay here your name is woof and you are 11 years

old okay and maybe this should actually return a string

and it could just return that string instead of printing it here and in here

then we get the result you can see it says your name is Wolf and you're 11

years old and then since we have a VAR with uh pointing to a structure we can

go ahead and say woof dot increase age and then we say wolf h all right so the

H by this point is 11 and then we in we invoke this increased age function which

is mutating function and then we get the age of 12 all right so protocols can

Define kind of um constraints or kind of like an interface on objects that

conform to them and therefore can using extensions on those protocols can access

those variables and functions which are placed in here so it's kind of like

giving a blueprint so it's kind of like any object that conforms to me has has

to have this blueprint and then I can internally use that blueprint to my

advantage okay now just we've just like we've seen this

in here protocols can have mutating functions something that I want to

mention next but I think I just mentioned a little bit too early perhaps

but at least you get the point let's now focus on that mutating function so if

you say protocol vehicle I just want to show you another example

and let's say we have a variable speed and we say it should be an integer which

is getter and Setter so we should be able to set it and read from it okay

then we create a mutating function here increase speed and we say buy which

value like this okay so we Define this mutating function here and then we go

ahead and extend this vehicle like this and we implement this mutating

function all right so what we did here was a little bit um is not optimal

because we implemented a mutating func increased age inside the extension so

whoever looks at our protocol won't immediately understand that there is a

mutating funk available on it so if you wanted to make this code a little bit

more readable we would place this function a declaration here as well okay

so let's go in our code again and we say in the implementation of our protocol

increase speed by value will actually have an implementation that's a

self.speed is plus equal to Value like that and we can bring this value down

here to make the code a little bit more readable as well

and perhaps decrease the size of the preview as well

so let's then go ahead and create for instance a a concrete implementation of

this vehicle protocol so we say struct bike and then bike it will have a speed

oh let's actually move this and say it is a vehicle all right then we get an

error from uh Swift saying that it doesn't conform to Vehicles simply

because it didn't have the speed variable then inside this bike we create

an init and we say self dot speed is zero you could have also done it like

this that also works it kind of depends on

how you like to implement and do your implementations I've seen both and for

me both are fine it's up to you and your team to actually make a decision on what

uh can what convention you want to use for initializing your variables and

structures okay but this is completely valid syntax as well

after doing that let's create an instance of this byte let's say bike is

an instance of bike like this then we get the current speed it should be zero

because that's what the initializer did then we say bike increase speed by 10

and then we say bike speed all right so because we are conforming to the vehicle

protocol we can have access to this increased speed function in here now I

can see we're getting an error simply because a bike cannot be mutated you can

see we're actually invoking a mutating function on an immutable let constant

and the solution to that is to change this to VAR all right now you can see

our speed was zero and then it was increased to 10 simply because we

increased it using this mutating function defined and implemented on the

vehicle protocol all right so that's one thing I mean that's not

one thing that's quite a lot of things about protocols but at least you get the

idea of protocols now protocols can also be used as a conformance uh how do you

say it blueprints kind of so let me just explain how this would work

you can at any point in Swift use the is syntax or a keyword in order to check

whether an object conforms to a protocol or not because any class or any

structure can conform to at least one and actually not at least at least zero

and at most unlimited number of protocols so a structural class doesn't

have to conform to any protocol or it can conform to one or more protocols

that's what I'm trying to say and if you want to at any point check whether an

object conforms to a protocol you can use the is syntax let's have a look at

that let's say we create a function called describe and it takes an object

of type any and we haven't talked about this before but any is pretty much as

its name indicates any object okay then we say if object is a vehicle then we

say uh object conforms to their vehicle protocol

else object does not conform to the to the vehicle protocol all right then we

can go ahead and call this describe function and describe our object of bike

and then you can see since by conforms to the vehicle protocol then we get this

printed to the screen however if we had a structure of warm or at work warm and

it didn't conform to the vehicle protocol and we sit warm as an instance

of warm and then we just say describe more then you can see that we will get

this message printed to the screen object does not conform all right so now

that we've done that let's just remove this warm I don't like to have worms in

my coat so at least you get the point now with

with that as well now there's one more uh one more thing

that we have to talk about when it comes to protocols and that is I mean we've

talked about is but we haven't talked about as and as with a question mark and

they make more sense when we when we've already talked about optionals and we

haven't talked about optionals yet we'll talk about optionalism in like the next

three sections of this video but I just want to name it as well so you know that

it exists in Swift so using this as syntax you can

conditionally promote an object to a specific type so in here you can see

object is vehicle and if you say object dot you don't have any anything to do

now with this I mean you cannot do anything with this object even though

you actually said if object is a vehicle then I kind of would expect us to be

able to invoke these functions on that vehicle because we actually asked Swift

is it a vehicle then we come here but Swift doesn't understand the syntax as

good as it understands as like this and the reason behind that is You're simply

just doing an if statement in here saying is it that then do something but

you didn't actually promote this object to that type all right so any is like a

very low object type however this is sitting a lot higher in the hierarchy

and that's the reason we say promote so let me actually show you an example

let's say that we have uh that we have let's say a bike in here

and bike is a vehicle which has increased speed all right but we want to

create a function that that can allow any object to come in and if that object

is a vehicle kind of like this then it will increase its speed by 20. all right

so let's say funk increase speed if vehicle

and then the parameter to this is an object of type any all right then in

here we say if then we create a VAR and the vehicle is equal to this object and

then we say is it a vehicle like this with an as syntax if

it is then we say vehicle speed you see now we get access to all properties of

that vehicle because we promoted this object to a vehicle so it's not similar

to is because this won't allow us to access

the vehicle objects and hear our Properties or functions then we say get

the current speed vehicle increase the speed by 10 and then get the speed again

in here okay otherwise we say this was not a vehicle so let's then go ahead in

here and see what happens so let's say increase speed

if vehicle and then we pass our bike in here all right let's see what happens

are we getting a lot of Errors perhaps from Swift it crashed no okay so you can

see we got the value of 10 in here okay and then we get the value of 20. right

here okay now you may be thinking about what

happened in here bike let's have a look at bike you can see its speed it was

zero in here and then 10. and then we call this function which should have

increased the speed to 20. but if in here we say bike speed what happens do

you think it's 20 well no it is 10 actually and the reason behind that is

that bike is an instance if you go back to it is an instance of a structure

called bike so it's a structure structures are value types meaning that

when you call this function with an instance of your bike you're not

actually passing the memory consumed by this bike as a reference to this

function what are your what are your in fact doing is that you're making a copy

actually not you directly but Swift is doing it doing that Swift is making an

entire copy of this is making a copy of this entire object and passing it in

here so in here this VAR actually is pointing to not the same memory address

that bike is consuming but it's pointing to a completely new variable in the

memory and is allowing it to basically be increased by a certain speed which is

not affecting the spike however if this bike was an instance of a class so if we

went in here and said bike is actually a class let's say class now you can see

calling this function it will actually change the speed for you to 20. so

calling this function it affects the actual instance of bike itself see the

speed is exactly the same but if you go back to a struct you can see the speed

of your bike will be 10. all right so keep that in mind when you're working

with protocols protocols and classes and structures together go really hand in

hand to create amazing object oriented applications in Swift but they can make

things also a little bit complicated so keep that in mind when you're working

with these um with these Concepts

good that's quite enough about protocols now that we've talked enough about

protocols let's go ahead and talk about extensions you've already seen examples

of extensions and how they work in Swift but we haven't really focused on them so

let's do that now let's go oh I don't have to do that let's create a new

playground playground and in here we say blank playground and we say extensions

all right like that and here as well then we say create

and just like usual we say we just need foundation for now all right

so extensions as their name indicates they can add functionality to existing

types they can extend existing types so let's have a look at an example let's

say that we have an extension on data type of integer and then we say we have

a function called plus two which returns an integer and since this function is an

extension of int self in here refers to the current integer instance okay then

we say we return self plus two all right then we can go ahead and say 2 is equal

to value of 2 and then we say 2 plus 2 and then you can see then we get the

value of 4 here in our playground okay so self inside extensions refers to the

current instance meaning that this two in this case all right so self in here

is actually two so if you just print self and then you say return self

self plus two you can see self is indeed the value of 2 in here which is what

you've specified here so if you change that self will change to that as well

all right so keep that in mind that's one example of an extension

Now using extensions you can also add initializers to existing types which is

one of the most powerful features of extensions in Swift let's have a look at

an example let's say that you create a structure called person in here and you

have a first name string and then let's last name last

name as a string okay now what you want to do is to create a I mean you want to

behold and sorry you want to hold on to this person's Constructor or initializer

that Swift already creates for you with the first name and last name so you

don't want to change that but you also want a Constructor that takes in a full

name however if you go in here and say init full name screen

then you can see all of a sudden your person doesn't have any other

Constructor with a first name and last name anymore your only Constructor

inside the structure itself will replace the existing Constructor okay and that's

not good so what you want if you want to for instance have a Constructor

initializer on this person that doesn't replace the existing in initializer that

Swift creates for you then you need to create an extension on person

and then you go ahead and add your initializer in here okay now you can see

if you try to initialize an instance of person you have both of these

Constructors the default one that Swift created for you and also your own

Constructor which is inside the extension all right so let's inside this

Constructor go ahead and grab the components out of this full name so we

say full name components is a function and we separate

the components by space all right and so we say let components and then we want

to pass these values that we extract from components so we say self in it

into our Constructor then we say the first name is actually components first

otherwise fully and we say in here as last name is components last otherwise

fully just like that all right so this is very dumb implementation to be honest

with you but I mean it's not too dumb either it is literally taking the first

part of a name and the last part of a name assuming that this is the first

name and this is the last name and anything that is between them separated

by space is the middle name which we don't care about in this instance okay

then we can go and create an instance of person so left person is a person then

you can see we have both Constructors or initializers and we're going to use full

name in here we say Foo and bar you can see they're separated by space and the

first component is Foo and last name and last components bar then we say person

first name and person dot last name all right so that's another powerful future

of extensions in Swift in that you can extend an existing structure for

instance and add a new Constructor or initializer to it okay

now apart from that you can also extend existing types and add conformance to a

protocol to an existing type so that's also really cool so let's create a

protocol in here we call it Goes Vroom okay so that's our protocol name

and this protocol what it does is that it has a VAR room value and it's a

string and it should we should be able to read from it okay and then we create

a function we say go vroom and then this function returns a string now we go

ahead and extend our goes room and then we add the default implementation for

this go vroom function and then we say self Dot vroomvalue

goes room so remember this is just a variable that

we know any instance conforming to our protocol should have access to and then

here we're just adding the default implementation for this code firm

function and returning this string as its return value all right then we go

and create a car instance we say struct car and this car conforms actually we

don't want to conform yet and in here we say let's manufacture is a string and we

say let's model is a string as well I guess this is just a simple car

structure then we can say let model X is an

instance of car with the manufacture of Tesla and its model is going to be X

and after creating this instance we can go ahead and actually extend this model

X so we can say model X extension sorry extension of car then we say car now all

of a sudden conforms to the Goes Vroom protocol you will get an errand here

telling you that you're not actually conforming to go Gold's room and the

reason behind it is that if you go to ghost room you can see that we have two

requirements one is that we have any type conforming to goes from protocol

has to have a variable called room value that's at at most and at least readable

uh however Carr doesn't have that and that's the error that we're getting in

here so let's just get Swift to fix it and you can see it creates a computer

property in here called vroom value which should return a string okay and

for our vroom value we're going to say it is self manufacturer model

and self.model all right and then all of a sudden this car instance conforms to

That Goes Vroom protocol meaning that this model X all of a sudden gets a

function called go vroom and if you do that you can see it says Tesla Model X

goes room and that's because vroom value is a variable that is implemented on all

types that conform to God's room but ghost room doesn't really know what this

value actually is it just extracts that value and adds it here and then says

goods room however it is the conforming types responsibility to return this

value and in this case the case of car structure we're just saying manufacture

and then model X so it says Tesla Model X goes through this part is provided by

conforming types such as car and this part is provided by the ghost room

protocol itself okay so you can also have I mean now now that

we've talked about that let's go to the next concept and that is having

extensions on classes and with convenience initializers so you can

actually extend existing data types and add convenience initializers to classes

and not structures because structures don't have convenience initializers but

classes can so let's go ahead in here and create a

class and we call it my double so like a class that holds on to a double variable

and we say VAR value double and then we can say an initializer that

takes a value of double and we say self value is value in here okay

now you can go ahead then is actually this I don't think this needs to be a

VAR it can just be a let perhaps okay and in here then we're going to go ahead

and create a convenience initializer and which always sets this value to zero if

anyone initializes the instance of My Double because at the moment if we say

let let's go ahead Foo is my double you can

see that you always have to have a value available and pass to my double

initializer but if you don't want to have that you can extend your my double

class in here and say you have a convenience in it in here that takes no

parameters and calls self in it with a value of zero so this is literally

delegating its task to a designated initializer in the my double class but

it is a convenience initializer that is created inside an extension so you

that's one of the powers of extensions you can extend an existing class and add

a new convenience initializer okay so then you can go ahead and say my

double to create an instance of it and then you can just say value all right

you can see now the value is zero this is another fancy way I'm of basically

accessing the value you could have said let my double is an instance

of My Double and then you could have said my double dot value so that those

two lines of code work pretty much I mean achieving the same thing okay

now apart from extending I mean not apart from but I mentioned that

extensions can extend structures and classes but guess what they can also

extend existing protocols so so you can see in here we have a protocol called

ghost room and it has this go room function you can go ahead and extend it

you can say extension goes room and then in here you can add a new

function say go of room room even more okay so this is just a ridiculous name

I'm completely aware of it but you can um what I'm trying to say is that you

can extend an existing protocol as well and add new functionality to it and by

doing this every data type that conforms to that protocol would get your new

function by default so you don't have to do anything okay then in here we just

say self room value is vrooming even more like that okay

then all of a sudden model X that we created in here which conforms to which

is an instance of car which conforms To Go's room gets this new functionality by

default so then we can say Model X go vroom vroom even more and then you

can see that value being printed to the screen as well is rooming even more okay

so extensions are I would say one of the most fun aspects of any programming

language and in Dart for instance they're called mixins as well and

they're available in some other languages such as rust as well so

they're really fun because they allow you to make existing things and types

better they can kind of get out of hand sometimes if you're like misusing them

in that when you're extending generics types for instance you can just go crazy

with generics but as long as you're comfortable and you and your teammates

are comfortable with those extensions I would say go for it now we've talked

enough about extensions for now at least let's go ahead and start talking about

generics which is a topic a lot of developers try to avoid but I think you

need to embrace it because if you look at most modern toolkits and Frameworks

such as Swift UI they could have not been made possible

without generics Swift UI is pretty much based entirely on generic types so I'd

say one of the best practices of becoming a better developer is to

embrace generics learn how to use them learn how not to use them and truly

don't be scared of them so practice practice until you get the concepts and

then use them wherever you think and your teammates think makes sense

so without further Ado let's start talking about generic so I'm just going

to press command in here and say a playground and we say generics

like this and ensure you're creating it inside your workspace so Swift crash

course and we create this generics uh

playground import foundation and we say automatically run this all right I'm

going to get rid of the export to the left hand side now generix is for me at

least it's used to avoid writing the same function multiple times or writing

the same code multiple times all right now

generics they kind of look a little bit strange

but they really at the end of the day once

you've written the code for generics you can use them in so many different ways

and you will be amazed by how powerful they are okay so what we're going to do

as the first example of generics I'm actually gonna jump right in and write

kind of like a scary looking function all right but what this function is

trying to achieve is that I mean its mission statement is kind of like this

it wants to expect any numer any numerical data such as a floating value

or double value or an integer two of those values so it takes a left hand

side and a right hand side and it expects us to pass it a function that

can perform an operation on those two values and return a new value in

response such as let's say x x is 10 and let's Y is 20 and then we say let's C is

equal to X Plus y so this plus function takes a left hand side and a right hand

side and returns a result which is the equivalent of adding those two values

right now you can have minus in here you can

have division in here it can have multiplication oops if I can write it so

all these functions take a left hand side and a right hand side so they do

some operations and they're actually operators we've talked about operators

before okay so let's say then we create a function we say a function that

performs a task and we say

it's an operator that takes an integer and an integer and returns an integer

kind of like this okay and then oops and then we say it

performs this operation on a value on left hand side of type int and

and right hand side of type int and then in itself returns int okay so you can

see it's performing an operation that actually does the job I think they

actually did something like this when we were talking about operators and we

actually put this as a trailing closure I remember but it's similar to that at

least and internally what it does is calls that op function and passes the

left hand side and right hand side to it and returns this value in return

then you can go ahead and say perform Plus on 10

and 20. and then you can see it will just say 30 as a result because this is

actually a function all right and you can say plus and then you can say minus

of course you can say multiplication in here

and you could also say division in here okay

so maybe we could say 20. and 10 in here for the division so that

we get proper values printed to the console

so this is an example of this function now your teammate comes to you and says

could you make this function work with doubles as well then be like um okay

then I'm gonna change this to double and this two double

and then this to double and then you have to go and change this to double and

this to double and this to double then your code kind of works all right

but the result of these is actually now a double so if you look at Foods data

type is a double what happened to your integers well you change the function

signature from int to double and you lost the ability to work with integers

then you'd be like okay then I need two functions one for integer m one for

double then you call this perform int so we say let's see if I can change this

name perform int and then you say okay I'm smart enough I go ahead and create a

perform double and I make sure that this double works with doubles okay so

whoever wants to work with doubles calls perform double and whoever wants to work

with integers works with uh perform int then your third colleague comes and says

okay but I want to work with CG float and which is another data type which is

inside the core Graphics framework which we haven't worked with right now but you

can say core graphics and then you can say let X is CG

CG float is equal to one it's kind of like a double actually

and then you say oh a CG float then I have to create another perform function

which is called perform CG flow however as you can see this is not a

very maintainable way of working so this will just increase the size of your code

base and you have to constantly go ahead and add new functions to your

application wouldn't it be really good if we could

create a function that works with any numerical type

and if you look at integer let's go to anything here and then we see signed

integer and then side numeric you can see that this sine numeric protocol

conforms to another protocol which is called numeric okay and if you have a

double value let's say let's X is a double 1.1 if you go to double and let's

say numeric there should be an extension on double

extension double which makes it conform to a

that's numerical type as well so let's say binary floating point I think and

then expressible by Flo oops not that long perhaps

by integer literal hashable so stridable it is one of these implementations

which conforms double to add that numerical type that we were

just talking about I'm not sure which one it is we have to dig deep inside

Swift source code basically but what I'm trying to say is that both

double uh and int conform to a protocol called a numeric numeric

now if we could somehow in here say that this function works with any numerical

data type that would be really good so let's change this to numeric

and then we say numeric numeric and here here and here okay

now you'll see what happens inside your sift code and Swift tells you okay I

understand you want to work with the numerics but you can't just add them

like that you can't just say that this function expects numerics numeric is a

protocol and if you want to use it here you have to use generics so the way to

use generics is that you go right after your function name and you just open

these less than an equal signs kind of like in here then you designate a letter

usually a letter but sometimes people use words as well but it is very very

common to use a letter so you say Okay I want to represent numeric with a letter

okay I can't just say new American here because that is an existing data type

let's just say n okay as a numeric then you say n should conform to numeric data

type or protocol then anywhere inside your function signature where you're

using numeric just type n okay so in here in here right there

there and also here and also for the return value of your function

all right so now you see all of these errors are going to go away so you can

see all of them went away and your function still works and if I say let X

and then I look at the data type for X you can see X it is understood to be an

integer but how you didn't say anywhere that you're working with integers

and that's the power of generics the compiler is uh is basically inferring

the data type based on the values you pass here so if you say 10 and 20 then

it knows that they both are integers and the result should be an integer and

let's change this actually it's not perform int anymore it is perform okay

now if you go and do and let's say let's X is perform on 10.1 and 20.2 all of a

sudden X is a double because compiler understood that oh these both values are

actually double they're not integers anymore so it substitutes the return

value which is indicated by this n generic value to the actual values you

pass through this function in here okay and you can also go ahead in here and

say 10.1 and 20 what do you think X is going to be now

well the compiler is also intelligent enough to promote the value the return

value to the more complex or more complete data type the more complete and

precise data type in this case is not integer but it is actually double so if

you look at the data type for X is indeed double all right so that was the

first example of using generics in Swift and I know it could look a little bit

complicated but the more you work with generics you the more you will actually

appreciate them we've now seen this example I would say

actually a quite a simple example of generics in Swift now when you have

functions that have multiple generic parameters in this case we have just one

generic parameter that we've called n of type numeric

but in other functions you might have generic parameters maybe two two or

three of them or even more in that case the function signature might be getting

quite long you would say R is something and D is something else so looking at

this function you you would probably just get a panic attack just looking at

the function signature and that is why Swift allows you to create function

signatures for or generic function signatures where the direct generic

parameters are stated at the end of the function declaration itself and right

after actually the return type so to demonstrate how that works as well let's

just take this that we have in here the code that we have in here and let's go

and paste it right there okay and we will just name this function and perform

two and change all these instances to perform two just to ensure that

everything is working as expected so in order to create a function or generic

function where the generic parameters are defined at the anode function

signature you have to remove this generate type right here or as many as

generic types as you have you remove them from the beginning or attached to a

function name and you go right after the return value and then Define them right

there using a word clause so in here we then say where for instance n is numeric

so this is an alternative way of creating a generic signatures for your

um or for your functions and in here you would of course you would still have n

in there but you don't actually tag and as a meaning of type numeric so this is

just a an alternative way of doing it and some developers prefer this way

simply because in here you could just say A B C D or your generic types and at

the end you could actually say what those a b and c and d are in fact of

type of all right so just keep it in mind it's it's a it's an alternative way

of defining your generic functions and it will just perform exactly the same

way it did in the previous example okay now any data types such as a class and

actually I can't say any data but classes and structures in Swift can

conform to multiple protocols they don't necessarily have to conform only to one

protocol okay and using this you can basically create generics that are

um that are conformant to multiple multiple types so let's have a look at

that right now and let's create and let's create let's say that we

create two protocols in here we say protocol can jump okay and then in here

we have a function that says jump so any type that conforms to can jump should

have a jump function and then we create another another protocol in here that we

say can run okay and can run has to have a run function then we go ahead and

create a structure in here we call person and we say it can jump and it can

run like that all right so this is conform conforming a new structure to

two different protocols we can get a swift to fix these functions up for us

in here you can see in run we say running

and in Jump we say jumping jumping okay I think the indentation was a little bit

wrong all right now we have that now let's say that you want to create a

function called jump and run okay so let's say flunk jump

and run and you want to take in a value in here of some type you you want to say

Okay I want some value to be of any type and in here I want to say value jump and

value the run but since this value at the moment is of type any it cannot have

the ability to invoke that function jump or the Run function so you could say

Okay I want value to be of type can jump if you do this then you can do the jump

function but you can't do the run function all right so in here what you

need to do is to go ahead and Define a generic data type in here let's say t

and we say this data type can run can jump and can run like this and then

inside the function signature itself you say the value is of type T now you can

see if you type value you have access to jump and run functions so this is a way

of combining multiple protocols in order to create a generic function signature

where you have access to not only one protocol data but also multiple as long

as basically you can make this as long as you want to all right

so then we can go ahead in here and create an instance of person we say

person is an instance of person and then we can say jump

and run with the value of person and we can actually change this values internal

sorry external parameter type to nothing so we can just say jump and run person

in here okay now you can also have extensions on

generic types and one generic type that is very useful is actually we haven't

talked about them so much about their arrays and I raise you to find them like

this you could say let names for instance is Foo and bar now if you look

at the data type for names you can see it is an array of string so it is

denoted by these square brackets now you can actually look at if you just type

this is a string in here and let's see if you can find the data type for array

so if you say array of strings so this is this is a an alternative way of

writing the same same text instead of this you can just do syntactic sugar

here and say array of string now if you go to array you can see it is a

structure and it is a generic structure basically it's working with a generic

argument called element now you can also create extensions on

generic types so by simply saying extension Offspring You're basically

extending an array of string and this is new format actually there's a new syntax

in the latest Swift versions previously you have to say extension array where

element was equal to string so this is the old

syntax but the new syntax you can just simply extend an array of string which

is a lot more readable okay then what you can do in here since you already

have you've told the Swift compiler that you're extending an array of string if

you create a function let's say we want to create a function on our on any array

of string that finds the longest string okay so we say longest string and we

return an optional string we haven't talked about optionals yet so just for

now know that this means that we can either return actually have we talked

about options structures enumerations protocols extensions closures no we

haven't yet we will talk about optional soon okay but just know that this means

it can either be a value or it can be the lack of a value equal to nil all

right so and the reason behind is that you can always have and the reason I

mean this is an optional string is that any array like final names is an array

of string in here it can actually be empty okay so if this array is empty how

can you find the late at the longest string in this array well you can't

there are no strings in here okay finally it should be let right so the

reason this is optional is because of that

and then what you can do in here is to say let dot

um so you sorry you say self-sorted and this is I mean to be honest you don't

have to know exactly how this is working and this is just an example okay so we

say sorted and then we say left hand side string

and then we say right hand side string and we want to say left hand sides count

the number of characters in the left hand side should be more than the right

hand size characters and then we say take the first argument you can see the

first argument is then deduced to be of type string as simply because we are

extending a generic type whose elements are of type string and if you look at

this property you can see it is using the same generic type call Elements all

right so that's also extending generate types and then you can go ahead in here

and say let's say we create an array of strings we say Foo

bar and bads in here has one string and then Cox in here then we say longest

string all right then we can get the value of bar and pass it to the console

or the playground console whatever you want to call it okay

then we have another topic to actually discuss and this is this goes to a

little bit more um I would say Advanced but I think

generics are Advanced topics to start with so we shouldn't be scared of having

a look at some Advanced topics in here so let's go ahead and talk a little bit

about Associated types in protocols okay so and this is this makes generic

protocols we've already talked about protocols before but we haven't talked

about generic protocols so let me just show you an example and demonstrate how

generic protocols work in the beginning it might not make so so much sense but

as we go on and complete this example it will make hopefully more and more sense

to you okay let's create a protocol in here we call it view all right so

anything that can that can be displayed to the user and we call it just view all

right we say any view should have a function on it that is called add sub

View and it is basically using the same view so it says anything that's a view

should be able to add on another view to itself alright then we go ahead and

extend this view we say it we had the add sub view as a default implementation

in here and we say by default it is empty all right so the end the default

implementation of add sub U doesn't do anything then we go ahead and create a

structure in here we call a button and we say it conforms to the view protocol

and at the at the moment we say it its implementation is currently empty okay

if we didn't have this default implementation of the add sub view

function then button structure would have had to implement the add sub view

functioning here as you can see suggested by the playground all right

so let's remove these comments from here we go back to how we had it before

then what we're going to do in here is to create a protocol and we say and we

want to basically represent every object in our system that can be turned into a

view let's say you have a struct person okay and then you say it has a name and

then you want to say I want to somehow present this person on my user interface

and then you say okay I want to make it presentable all right so you could

Define anything in your system that is presentable as a View using a protocol

let's say protocol presentable as view all right and this is kind of like

hypothetical at the moment but later in this course we will actually talk about

mvvm in iOS or Macos and watch us using for instance combine and Swift UI plus

RX Swift on RX Coco but for now just this is a hypothetical protocol but it

is very real actually I use this in production today so

and I just want to give you an example of how this could look like all right

now if you want to turn a protocol to a generic protocol you use a syntax or a

keyword called Associated type and using Associated type is almost as if you say

presentable ads view has some sort of a generic parameter but this syntax isn't

accepted and so if you get an error okay you can actually see it says an

Associated type name V must be declared so let's go ahead and Define this we say

Associated type and we say view type should be any data type that conforms to

the view protocol you see what we did in here we didn't just leave it empty we

said if something is presentable as view its view should actually be be of type

view all right so it can either be a button or it can perhaps be struct table

here's a view all right and maybe this struck the person will conform to

presentable as view and say that my you type is actually a table all right again

this is hypothetical at the moment at least

then we say any object that is presentable as view should be able to

produce a view for us to display the user so we say produce view is a

function okay and this guy should actually produce a view of type not view

but view type all right so if your view type is for instance button then this

function should produce a button if your view type is table then this function

should produce a table then we can't go ahead and create the

next function in this protocol let's let's just call it configure so we say

anytime we want to present a an object as a view we can allow it to configure

itself using a super view as its reference so super View and we say this

is a view as well and we save this view is view type so we say the super view

could be any view but this view oops type but this view should be is of type

view type which is a generic parameter to this vertical okay and last but not

least then every object that is presentable as view should have a

function on it that is called present all right and in here we say view is

view type and then we say on super view view all right so this view we're

already sure it is of type view type because this configure function sorry

this produced view function actually produces a view type and that same view

will be passed to this percent function okay and a superview should be anything

that is a few okay so that that was the X their protocol definition itself all

right let's go ahead and Define implement it and basically do some

default implementation for some of these functions inside this protocol so we say

extension presentable as View and now this is a generic protocol simply

because it has an Associated type all right then we go ahead and configure our

we write our configure function in here so like that

let's just paste it in here and we say it's default implementation is empty by

default all right then we will have a we will implement the present function all

right like this and upon presenting a view on a super view we just go to super

View and we say add sub view view all right because we already know anything

that is a view has this add sub view function on it so we just call it all

right then what we can do to make this all very exciting we say we create a

button called my button which is presentable as a view all right then we

know that this function and this button has to have two function implementations

and they're the remaining two functions actually we don't want to do that so you

can see presentable as view requires four actually three functions it has a

produced View and it has a configure Ampersand and these two functions at the

moment have default implementations right here but the Purdue view function

doesn't have a default implementation so you can go ahead in here and say that

you want to Define produce View produce view okay and then we change

this and we say this actually returns a button as we've defined it in here

button is a view all right and according to our protocol implementation the

producer has to produce a view type that conforms to the view protocol and button

does that it conforms to the view protocol in here okay so inside produce

view we just say we return an instance up button just like that all right now

what's going to happen is that you don't have to implement anything else except

for this but if you want to go ahead and for instance do it as configure function

in here so as soon as you start typing it let's say configure you can see then

a swift understood that super view is a view however this view is a button but

how they didn't understand the answer button the reason is that we changed the

implementation of produce view so that it produces a button then Swift went to

this protocol implementation in here and said oh produce view is producing a

button so everywhere in this protocol where I see view type I'm going to

replace it by button so it did this pretty much button button and button you

can actually go ahead and test that by adding for instance also at the present

function in here you can say present and you can see superview the view is a

button so that's how generics work basically in in Swift protocols okay so

it's very very simple when you look at the whole thing but if you go into

details you can actually see there's lots of things to learn about how

generics work with protocols especially and Associated types so just know that

for now that protocols can become generics using Associated types and

sometimes in Swift you need to know about them and you need to use them but

if you're not working so much with generics you probably don't have to

bother so much with Associated types but again if you feel intimidated by

generics and Swift I think you need to tackle that fear and go ahead and

actually play with generics so much that you become so comfortable with them that

it becomes a part of your day-to-day tool and day-to-day way of working with

swift okay now if you want to extend generic

protocols just like you have extension on for instance here and you can see we

have extension on this generic protocol you can go ahead and actually

constrain your generic extensions to specific types so let's say that you say

extension presentable ads View and then you can say where view type view type is

equal to a button all right this way you're training extension on any object

that conforms to presentable as view as long as that object's view type is a

button if you did this let's see what Swift says actually so we're just

creating a simple extension Representatives view if you add a

function to this any object that conforms to presentable svu's protocol

is going to get your extension values and or variables and functions however

this way only presentable as view conforming objects that have a view type

of button will get your extension all right so let's say func do something

with button so we are adding a simple function in here and we'll say this is a

button all right then let's go ahead and create a button we say button is an

instance of my button and since my button conforms to the presentable ads

view protocol we can say button do something

with button right however if we went ahead in here and set structure table is

also a view actually let's go to my button and we

will just say my button is we copy that code and we go ahead in here and we save

my table okay my table and in here where we have button we create another struct

and we say table is a view and we say it's empty as well all right then we go

back in here inside our my table we say that my table produces a table and in

here we just create an instance of table and we change this as well to table all

right so and we can remove the configure function as well we don't have to have

it in there now if we go ahead and say my table table is an instance of my

table if you say my table dot you can see that you don't have access to to do

something with button function if you want my table to have the same extension

do something with button and first of all you'd have to change the name of

this function so you say do something with view for instance

with View and then you also have to remove this generic constraint from here

because my table doesn't produce a button it actually produces a table then

your table my table will have to do something with view function as well all

right so I hope that this makes generics a little bit more clear

to us at at least by this point now apart from all of this you can also

as I mentioned like when we saw this extension on array of strings let's see

where we did that longest string okay you can also create other extensions on

arrays even though there are generic types such as for instance calculating

the average value of an array of integers so you can say extension

int so any array and that contains integers and then you can say a function

that calculates the average values and we say double

and then we say self reduce this is a special generic function on any array

and you start with a seed value and in here you do your operation you basically

what it does is that if you have values one two three four it says okay I start

with the value of 0. then I go to your first element then I say 0 and 1. so

then we say Okay Plus them together it says okay zero and one plus together

will be one then I will take this one and I will go to the next element which

is two and I will do this operation between these two one plus two is three

it says okay then I have three then I go to the next element and say three plus

three okay six six is here and this is I go to the next element six plus four it

will be ten all right so this is how reduce actually works if you take the so

basically this com if you say lip XXX and then in here we say XXX you can see

it's an integer but we want to grab the average then we have to divide this with

uh the count of this array so self.count and we have to convert all of these to

doubles so that they can actually produce a double value in here okay

you can see now it is quite uh happy with the code that we're written and

then you can say one two three and four and you get its average all right and

you can see then the value printed to the screen right here 2.5 all right so

if you had an array that was just like two and two or four and four in here

then the average would actually be the same value as you've entered in here 2

and 2 will produce two and four and four will produce uh four okay so that's how

you can extend existing data types that are generic such as race okay I really

hope that all of these examples made generics make a little bit more sense to

you if they didn't I think it is important that you go back and practice

generics yourself as well because without practice generics will probably

never make sense good we're done with generics let's go

ahead to the next section which is optionals so I'm going to create a a

playground in here playground and we'll say blank and we say options which is

also a very fun topic to talk about in Swift so let's just do that

good and then in here we say import foundation and let's just do this so

that it runs automatically as well and let's get rid of our project uh Explorer

to the left hand side all right so optionals indicate a value that might or

might not be present okay so let's say that you want to take a value and

multiply it by two okay so let's create a function that takes a value and

multiplies it by two so we say flunk multiply by two in here and then we say

value and you can see it's an integer and it

returns an integer as well all right then in here you just say value

multiplied by two in order to turn this data to actually

before I say in order to let me just explain what options then would do for

this function and how they would make this function perhaps a little bit more

fun to work with if you call this function multiply by 2 you always have

to produce a value in here so you can't just call this function empty we're

thinking that it will just produce zero if you don't pass anything to it okay

you can see that it says okay you have to pass a value to me in here then if

you don't want to do that if you just want to say okay if a value isn't there

just assume it is zero okay what you could do is to say okay value is

optional so you say it shouldn't it doesn't have to be passed on here and

furthermore you can assign a default value to it so you say value is an

optional integer that by default is not present

then what you can do in here you say if let's value so this is the syntax of

unwrapping an optional so you say if the value is present then return value

multiplied by two otherwise return the value of zero like this all right and

also there are other ways of actually doing this in Swift so you can see now

this function works fine because it's hitting this point since a flat value

syntax indicated that value is indeed nil there are other ways of doing this

you could actually change this code to this and do it like this you could say

it's an integer which by default is zero then it will work exactly as it did but

I'm just trying to demonstrate how optionals work and how a flat works it's

a little bit difficult to find hypothetical examples for using

optionals which is a little bit a complicated topic to explain and even

more complicated to find very trivial trivial examples of how to use them all

right but let's just leave this example as it is so now you can see that you can

call that function with either no value values or you could say you pass the

value of nil and it will produce also zero or you could say you pass a value

of 4 or 8 or whatever you want in here and this function will still work so

even it works even with the value of nil I don't know why our playground isn't

really running yet there we go so we got our values okay

you can compare optionals with nil nil is a special value meaning that the

absence of a value basically so you could say let H is an optional integer

and it is equal to nil all right so it is not present basically then you could

say if age is not nil age is there how odd because we expected it to not be

there else H is now correct okay so we kind of expect this Branch to be to be

executed right now and you can see that it is okay so that's how you can compare

a value not being nil for instance okay now if you want to take an optional

value and check whether it actually exists or not you should use actually

not you don't have to use but you can use the if flat syntax so you say if let

H if H is present then inside this block after if let age is not optional anymore

so you can see it is right here okay so then you could say h is there uh how odd

its value its value is H all right otherwise no age is present as expected

because we know that age is actually nil and we should get this uh printed two

that counts all right now apart from if let's way of unwrapping and optional you

can also use another syntax which is called guard and guard does the negation

of age basically so let's have a look at how Guard works so let's say we create a

function in here we say check age all right and in here we want to read age we

say we want H to be there if it isn't then we're just gonna return from this

function within message but if it if it isn't there we return with a message but

if it is there then we print something to the console for instance so you could

say if age is nil then you could say age is nil as expected all right

however there is another way of writing this function and the way to do that is

you say this let's say that this entire function depends on this age variable

right and however if you um if you type a function if you type your code like

this anyone reading this code might not fully understand that this age variable

is very important to this function's signature or dysfunctions functionality

and that is why Swift has an alternative way of doing this check so if your

function depends on some optional values and it can't really continue without

those options optional values actually be being present you need to perhaps use

the guard mechanism so in here you say Guard age shouldn't be nil else then you

say age is nil as expected and then you return okay so you're basically saying

make sure age is a nil if it is so this else reads if it is then do this and

inside guard you always have to return so if you don't return you actually get

an error so guards have this property that they need to return and because

that's the whole point okay and also using guard you can unwrap values as

well as we'll soon see so let's put this card in here and then we say the rest is

age is not nil here strange because we don't expect that and then we call the

check H function in here so we should now hit this Branch because age is

indeed nil so we can't just guard that it isn't nil because it is nil and it

will end up being here okay Now using guard you can also unwrap

values because you can see in here if I say let XXX is H and in here I say XXX

it is still an optional all right so um even in here if I select XXX as H you

can see XXX is indeed optional integer however in here we said make sure that

it isn't it isn't nil so it shouldn't be integer so I kind of expect XXX to be an

integer all right but it isn't and the reason behind it is that we're not

actually unwrapping this age we're just making sure that it isn't nil but the

rest of the function doesn't understand and the way to fix that is to actually

use garblet so let's say let's H2 int optional and we actually set a value for

it we set a value on zero okay then we create another function here we say

check age two and in here we say guard let H2

otherwise so if we go in here and say let XXX in here let's do a return and we

say XXX is equal to Age Two you can now see XXX is an unwrapped integer it's not

optional anymore and that is simply because we did a guard let all right and

then here we say age is nil how strange and then we return and then in here we

say Age Two is not nil as expected uh value is equal to

Age Two all right so this H2 in here is not uh this Valley anymore really it is

unwrapped within this function all right then we can call this function as normal

we say check H2 check H2 and we should then hit this line in here and you can

see the value of H is indeed printed to the console value is zero you can change

it to 10 if you want to and you can see that value being printed to the console

as well all right so that's another syntax for guard using guard let for

actually unwrapping an optional now optionals are actually an instance

of an enumeration this enumeration is called optional unsurprisingly so just

like you can switch on option on enumerations you can switch on options

so you can in here go ahead and say switch age all right and you can get

help from Swift to complete these for you this search statement you can go in

here and say fix it for me you can see this optional uh enumeration actually

has two cases let's see if we can find it enum optional there we go and it

either is the value of none meaning that it is nil or it has some value inside it

all right so in case of none let's just say age has no value as expected in case

of sum we can unwrap it and say let's say value and we say age has the value

of value like this and we can break in here as well break okay so age was nil

if you remember so we kind of expect to hit this casing here which is none and

it says age has no value as expected all right so that's how you would switch

basically on an optional value you can also go ahead and do simple comparisons

so if you could say if H2 for instance is equal zero so you could do that then

you say H2 is 0 as expected and it's not the nil and let's go to H2 and actually

make sure that it is zero so let's change it to zero and in here we say

else age to is not zero how strange all right and as

you can see the comparison is working so you don't so what I'm trying to say in

here you can actually compare an optional value with another value like

this without having to say if K slat or is it let case or case let I I always

forget that so you don't have to unwrap it using a case let's or using a switch

you can just compare it with an unwrap value like this as well

okay now you can also just like we did this comparison you can also compare

with the non or some cases so let's just copy and paste that code in here then we

say if H2 is equal to sum 0 and then you say the same code in here

so this these two are equal to each other I mean they're not equal but

they're identical to each other so it is completely up to you how you want to do

this code and for me if I see this code I don't assume that ah2 is optional but

is indeed optional and but if you write your code for me I completely understand

that oh H2 is optional so this is a little more descriptive of the problem

in hand so I actually would probably prefer this but it is up to you and your

team to decide on a convention on which one makes more sense to you okay now you

can also do optional something called optional chaining and and that means you

optionally access optional Properties or methods of some classes or structures so

let's create an example for it we say struct person

and we say let's name the string and we say left address is let's actually not

do that at the moment let's inside this structure create another structure

called address okay and in here we say let first line is a string and it's

optional all right so we if we have it at an address then this first line might

not be present and also uh additionally we go into person in here we say

addresses itself is optional so even if it is present it doesn't have to have a

first line but if it's not present it will be nil all right so it's like

optional within optional so this is optional within this optional actually

the other way around uh address is optional and within it there is another

optional property okay let's create a person in here we say Foo is a person

and we say it is equal to an instance of person with the name of Foo and its

address is nil we just say we don't have an address okay then if we say we want

to get this person's first line of address then we say if let Foo first

address line line is equal to Foo then dot address and optional optionally grab

the first line all right so it means address is optional we know about that

but go and grab its first line if it is present then we say um

E flat okay is equal to that

then we print it out through first line otherwise we say Foo doesn't have an

address with first line as expected so since we didn't have an

address for Foo at all then it shouldn't even have a first line okay so this

address basically Swift stops right here it says I can't go any further after

address because address it itself nil so I can't grab the first line of it even

if first line did exist the address itself doesn't exist okay so then we get

this message printed to the console now we can go ahead and do another like an

alternative way of grabbing this value is by first grabbing the address and

then out of the address grabbing the first line it is a little bit more code

and I don't actually think you win so much on it so I just wanted to show you

how you can do that as well let's say if let Food address is food dot address so

you first unwrap the address okay and then you say okay after that get the

first line as first line like this is equal to full address DOT first line

then you can say Food address and then you say first line all right but we know

that we don't get in here because food's address is in fact nil so we don't even

go inside this code in here and not in here either okay

now you can compare optionals using chaining as well so let's go ahead in

here and Define a bar person we say bar is an optional person actually and it is

equal to person whose name is bar and whose address is in fact an address

instance with the first line equal to nil all right so it has an address but

its first line is now then we say if bars and you see we're

accessing bar using an optional like a question mark simply bar simply because

bar in itself is an optional value if bars name is equal to bar

and bars address first line is equal to nil then we say bars name is bar and has

no first line of address okay otherwise then we can say

um seems like something isn't working right

because we know that Bar's name is indeed bar and it has an address what

its first line is actually nil okay but do you know this line of code actually

isn't saying that it has to have an address but its first line should be nil

it could actually work as well it will work as well if the entire dress is nil

so let's just change it to nil and you can see still the same code will be

executed all right so that's how optionality works it just continues

until it can't continue any further okay now you can also switch on options with

word Clauses all right using an optional chain so let's create a bass person in

here I'm just going to copy paste that code so we don't have to create many

persons and this time it's an optional person with an address that is present

and it has a first line as well all right then we can go ahead and say

switch on the per on baz address first line all right and in case we say in

case of a sum we say let at first line and we just break in here and we say

case and none actually let's not do that let's just say uh case first line and

then we can go ahead in here and add a where Clause so this is pattern matching

and so we're saying okay if the first line is available and using this word

clause is pretty much just saying and and the first line starts with uh the

string baths okay then we say bad's first address line is equal to

first line like that then we say case let's sum and then we say first line and

we don't have a word clause anymore and this one catches all then we say Bass

first address line that didn't match the previous case and

then we print the first line all right and then last but not least we also have

to cover the non case where the value the optional value is indeed nil we say

bass first address line is new and weird

okay because we already know that bass is first address line is in fact Bas

first line and you can see this being printed to the console it says Bas first

address line is bass first line as it was in here so you can have where

Clauses in your case statements for switching on optional

um enumeration or enum values okay now you also can choose to um

if you're using a flat or Gauntlet and you should do that uh as long as it

makes sense to you all right so let's create a function in here let's say we

say funk get full name and then we say we have first name as a string and then

we have a last name as an optional string and we produce an optional string

as well all right then we say we say that you have to have a last name

all right even though the function signature says optional we say that okay

you should have one we said if let last name

if we can unwrap it then we return first name and name and space then we

say last name all right otherwise otherwise we return nil all right now

that's one way of doing it so you can just in here say get full name and for

first name we say Foo and for last name we say nil then we call the same

function with uh Foo and bar as names like this so this one has a last name of

Nils so it should end up being here and you can see it's actually producing the

value of nil and this one has both first name and last name therefore it is

returning Foo bar as this result so that's one way of doing it but you can

also go ahead and use guardlet so if you copy this code from here and then we go

and paste it right here we say get full name two and in here you could say guard

let last name otherwise

return nil and then you switch these statements

basically all right so you basically the way I usually read this is like this

make sure last name is present otherwise return

and then do this otherwise basically saying if last name is present okay so

after doing a guard let all statements after that card let if we hit them in

that in those statements the value that you unwrapped in here will be present as

a non-optional all right so that was also short and sweet about optionals and

there's lots more to actually explain about options and they pop up pretty

much everywhere in Swift and especially Swift UI Azure as you as actually we'll

talk about Swift UI later in this course as well but just know that they're there

you need to learn them if you're working with Swift and it is very advantages if

you can really master optionals and suit because they're pretty much everywhere I

hope you enjoyed this section of the course as well and in the next core in

the next section we're going to talk about error handling in Swift

now that we've talked enough about optionals let's first do some cleanup

here in our workspace so I'm just going to press command command W and close all

these tabs that we have opening here there are quite a mini and they're not

really contributing to so much right now rather they're just like making our

workspace look a little bit dirty so I'm just gonna do command W in here and if

you're in Visual Studio code for instance on Linux and or even actually

replace build build oh okay I don't know what happened really and even if you're

on Linux and you're for instance having Visual Studio code open with your Swift

files you can also close them if you're not really interested in having them all

open at the same time so as mentioned we're going to go and talk about error

handling right now so I'm just gonna press command n and say blank in here

and playground and let's say error Dash handling and I'm going to create it in

the main workspace in here as you can see okay let's press create in here here

and say import foundation and like usual we're going to go in here and say that

it should automatically run all our code okay so error handling is one of the

most important Concepts in any programming language that supports

errors and exceptions and really the points of errors and exceptions are to

tell the the caller to our code or whoever is using our code that something

has gone wrong it's either the failure of the code that we've written such as

an error or it's the failure of the person calling this function or code

such as an exception so there is a little bit of a difference between

actually errors and exceptions in different programming languages but in

Swift usually we only talk about errors so meaning that the code found out that

something hasn't gone according to the plans and then it throws an error and

actually the word for it is actually throw in Swift indeed so there's a

keyword for it called Throw okay and it is the same thing in many other

programming languages actually it is called throw in Dart for instance as

well so let's have a look at an example of

throwing an error in Swift and catching it so we're going to create a person in

here let's see if I can spell struck person and let's say we have a first

name uh it's an optional and we say last name optional string as well okay then

we want to create a function in here called get full name and this function

should ideally return a string okay so we're going to say funk get full name

and we say it returns a string right however how can it return a string if

first name and last name are both optional meaning that they could at any

point both be nil or one of them could be nil and in those cases we cannot

produce a full name so the goal of this function is to return a string it

shouldn't really return an optional string because the full full name

shouldn't be optional then what we're going to do in here we're going to say

okay it is going to try to produce a string but it may actually throw so we

say throws okay so the function throws but inside is it will throw all right so

that's how the how the verb and the noun basically work

uh actually I think it is a noun yeah so the function is marked as thirds meaning

that internally it can throw an error now we're going to go ahead and Define

our errors inside this structure then you don't have to Define them inside the

structure or the class that throws them but it is usually good practice to

Define them within their enclosing structure or class so so to associate

the error objects with that structure or class okay so we're gonna go and say

enum errors for instance it doesn't have to be colors you could call it Myers or

person errors whatever okay person errors also works but in here we're just

going to call it errors and we need to ensure that this enum conforms to this

error protocol okay you can see it is a public protocol okay so you cannot throw

errors that are not um actually your enum if you're actually

going to throw its cases the entire enum needs to conform to the error protocol

so that's their role basically that we're going to see the first case

of the error is for instance first name is nil we're going to say then last name

is no and we're going to say case both names

are nil so these are the available errors that this function can throw so

these are the three things that can go wrong either the first name is no or the

last name or both in any other case means that name and last the first name

and last name are not nil and we can calculate the full name successfully all

right so as option as we've actually learned in the optionals section of this

video optional data type is a it is an enumeration meaning that we can do

switch on them so if we want to basically learn whether these two are

both not nil you could either do it like this a flat first name and let's last

name then you can produce the first name and like this first name and then last

name this then you should say else if first

name is nil and last name is not nil then you should say throw

and you say errors first name is nil then you have to do a

lot of else statements in here to understand okay first name wasn't nil

last name was nil and then throw uh last name is no and if both of them are

nailed then do this so it's a lot of if and else statements instead of all of

that we can just do a simple switch statement in here okay so let's just say

we switch and we say we switch on the first name and last name alright so this

is the first name we're doing is switch on two enums at the same time all right

so the first case and we want to handle one third both nil so we say case the

first one is none and the second one is none okay in this case both names are

nails so we say Throw errors both names are name the next case we

want to make sure that um we want to basically see if the first

name is nil but the last name is not milk so we say first name is nil and the

last name is not mil remember sum and non-30 cases of optional so if you go in

here do you remember these none and some some meaning that there is a value so

we're saying that there is no value for first name but there is some value for

last name in the case I'm not having a first name then we throw an err and we

say first name is no then we reverse these so we say in here

we take this non we say the first name is sum value but the last name is no

values and then we say last name is no and in the other case then we say in the

case of actually having a first name and last name so we say case let sum first

name and some last name

in here then we can calculate we say return and we return a string with the

first name and last name in here just like that okay so this is this is like

some sort of a pattern matching you could say in Swift and pattern matching

in Swift is very powerful I mean I would say it's even more powerful than pattern

matching for instance in Rust which is also in its in its own very powerful but

Swift has some really neat features when it comes to power matching with switch

statements for instance okay okay so let's go ahead now and create an

instance of this person's structure we say let's oops can I spell let's Foo and

we say person and for the first name we're going to

say Foo and for the last name we're gonna say nil all right so now we want

to go ahead and grab the lat the full name of this person and knowing full

well that the last name is no meaning that we're gonna get into this case

actually no sorry this case last name is no all right

so how do we do that because if we go ahead and say let full name is uh Foo

get full name get full name you can see that we're going to get an error from

Swift saying that actually it's very important that we see this in error it

says call can throw but is not marked with try it says Well it can't throw

basically it can throw an error but you're not trying to resolve that error

so the key word for trying to resolve I know or trying to actually call a

function for instance that can throw the keyword for it is try okay so you say

try however we're gonna probably get another error now and it says well it

crashed so the entire playground pretty much crashed and the reason is that this

function through but we tried this inside a inside a context that doesn't

have error handling so if you're using try then you need to be inside a context

in where in which you're handling your errors and that type of context is

created with the do keyword so you say do and then you place this code in here

okay and in here then you can go ahead and say catch and then you say got an

error and there is an internal error object in here which is just called

error okay and you can see now we are getting this in here and says God error

and it says last name is no so this is according to what we basically expected

okay so just remember do and catch and inside the cache block if you don't

specify anything in here and like let's e or something because then we're going

to get e in here if you don't specify how you want to catch in into which

variable there is an internal hidden variable called error inside every catch

statement okay good now if you also want to I mean this

this just catches every error any error pretty much okay so if you go in here

and say Foo and the first name and last name for

it is nil now you see you catch another error that's called both names are nil

okay but what if you want to catch specific figures you don't want to catch

every error you want to catch for instance specific errors you can you can

say I just want to catch person errors okay and any other error that happens in

here I don't want to catch it because remember inside the do statement you can

actually have a lot of code you can have a lot code in here and you can say let

blah is try something else okay and any of these statements that have tried

before them they can throw and they then those errors that are thrown could be of

different types So within the do statement you can have multiple uh lines

of code Each of which can also throw different types of Errors if that is the

case how can you catch specific errors and the way to do that is using the is

keyword after catch I'll show you so let's copy this in here that we have and

paste it and then we put the full name in here just so that we get the full

name printed to the screen if if any but we already know that there will be no

full name and in here we're going to say catch is person.heirs

I like this okay and you can see in here this

statement is still I mean let's see here okay we're gonna get rid of this one

because we already know that is a person error okay

so we have pattern matching basically on our catch and we can't actually grab the

variable out of it anymore so we we detected that it's a person error and

then the error variable isn't available to us anymore after doing this pattern

matching okay so this is how you would look for specific types of errors in

your catch statements all right now you can also catch specific errors I mean

here you're basically matching the error against a type but then you would be

asking yourself well but how do I know which one of these errors it is okay and

you can actually catch specific errors just by typing catch which error okay so

let's copy this code actually maybe let's create an another variable in here

we say let bar equal to person and in this case we say both first name and

last name are nil all right like this then we're going to copy this code that

we have in here and right after bar we're going to paste that and we say

full name is bar get full name all right and then in here inside catch we're

going to change this code that we have and instead we say catch person errors

and a first name is nil then we say first name

is no like that and then I copy I'll copy this and I say

we also want to catch last name is no and we say last name is no then we say

okay we also want to catch person dot errors both names are now and we say

both names are nil and otherwise at the end we have a catch all Block in here

let me say some other error was thrown okay so now this now you see you can

we're basically getting this error in here both names are nailed as expected

first name and last name or not are basically nil okay so this is how you

can catch specific errors as well this is how you can catch air types like

errors of this type but inside this we already know that we have three specific

errors and if you want to catch any of those specific errors you can do do just

catch and that that specific here okay so that's another way of handling errors

now we've had a look just at one function at the moment that can throw

but uh you can also do you can basically throw errors inside Constructors as well

of structures or classes meaning that you try to construct an object but the

parameters that you're passing to that object are somehow not valid and so as

you know the Constructor or initializer of classes and structures have complete

rights to do some validation on the data that you're passing to them if those

data for some reason are not correct according to the validation of that

structure or class then the class or structure should be able to throw okay

and I'll show you now how you can Define throwing

initializers or Constructors for structures and classes so let's create a

struct car in here okay and then we say let manufacturer and this manufacturer

is a string then what we want to do is to create a a

Constructor or initializer for this car that looks at the manufacturer that you

pass to us and if it is empty then it's going to throw an error because at the

moment you can say my car is a car with a manufacturer of empty string and this

is not valid according I mean to our rules you shouldn't have a card that

doesn't have a manufacturer okay so we want to basically catch this case we

want to see okay when you pass the manufacturer to the structure is it

empty if it is then we want to throw an error so let's go ahead and Define that

error first so we say enum errors and of course we have to conform to the error

protocol and we say case invalid manufacturer it is a very complicated

word to type in my opinion then we go ahead and we say okay we have an

initializer in here which takes in the manufacturer okay so I'm just going to

copy this so I don't have to type it anymore and then in here we say this

init function and it or initializer actually throws and then we say if the

manufacturer is empty then throw errors dot invalid manufacturer otherwise self

manufacture is equal to that manufacturer okay so you can see then we

don't have a problem in here the only problem actually we have is that we're

now calling this now Swift understands that this call to the initializer of car

is throwing but we're not trying it okay so let's go ahead and do a try on this

so we say do and we say we catch car errors

invalid manufacturer and we just have a catch Hall case in here as well so we go

into the do and we say try this code and in here then we say invalid manufacturer

and we say some other error just like this okay now you should be able to see

that we get this invalid manufacturer and pass in here so now the important

thing is also that if you're inside this do clause

and after this try statement you can definitely use my car so you can say my

car that manufacturer do whatever you want with it but you already know that

none of this code is going to be executed because the way we're calling

this car or the initializer of the car structure is that it's going to throw so

it's never going to reach this code in here so Swift reads this code goes and

calls the Constructor and it gets to this throw and just immediately jumps

out of this into its catch statements and says okay do I have any cash that

matches the error that was just thrown yes and it then comes here and it

doesn't even go here okay so you need to kind of follow the path of the program

to understand what is happening really now you sometimes may not really care

about the errors that are being thrown from functions or initializers for

instance and the way to do that is that you want to grab the value of a function

optionally so you say if this function is successful gets me the value for it

so you don't actually care about the errors okay so let's go ahead and have a

look at the syntax where and syntax work is using a flat okay so you said if let

your car is equal to try with a question mark so this is simply try with a

question mark simply means that you don't have to have a do and catch

statement it says optionally try to call this function and if it is successful

then give me the value back okay so we say Tesla and then we have access to we

say success your car is a your car like this

otherwise we say failed to construct and error is not accessible now so if you do

this statement in here so you can see we're passing Tesla actually to the

Constructor for our initializer for car therefore this logic is not going to be

called and and a proper instance of car will indeed be created meaning that we

will indeed come in here inside the success block all right so we optionally

try to call this function if it was successful if it didn't throw then we

come here and then we have full access to this variable all right otherwise we

get to this clause and as you can see I've typed in here in here we lose

access to the error that was actually thrown so we don't have access to the

error object really in here okay so that's how you can optionally try to

call a function that throws and grab its value

now you can also in some very rare cases very angrily try to unwrap a the value

of a function that can throw please know that in in all my years of

working with Swift I haven't done this I know that it is available but you you

and you should as a swift programmer know that it exists but you should

almost never ever use it but and the reason behind it is that this code as I

said angrily unwraps a function that can throw meaning that your program or your

application or your IOS app or watch OS app or Mac OS app will indeed crash

completely and completely close should the function that you're invoking

actually throw an error and the Syntax for it is not with an optional try it is

indeed with a a how do you call this actually exclamation mark okay so let's

go ahead and have a look at this we say let their car

is equal to try and we say car with a manufacturer of Ford and you can see now

this will indeed be a valid um car instance and I can say their car that

manufacturer nothing really happened and you think okay but why did he say that

you should never use the syntax and the reason is that

should this manufacturer be empty this whole playground will crash and it will

just you can see in here and encounter a crash and could not finish executing

this same thing will happen to your app and what whether it's a Mac OS or iOS or

and watch OS app your app will completely crash it won't look as pretty

as it did in the playground because the playground it still was open but it just

told you that it crashed if it is in a real application the application will

just completely close and the user will be baffled by what just happened so

please don't use the syntax try to always do I mean ideally you should do

do and catch if you can't do that please do try and please never try this never

tried this way of unwrapping values unless there is a very compelling reason

for it that you and your teammates for instance are completely comfortable with

okay now we've already looked at throwing

errors from functions but just know that you don't necessarily have to throw a

specific type of error in here we have just one enum and then here we also have

just one enum that Define our errors but a any function that is marked as throws

can't throw any error it doesn't necessarily have to throw a errors from

just one enumeration so let me just show you how that will look like let's create

a struct in here and we call it dog all right

like this and inside this let me actually create some empty spaces so we

can do this so inside the dog structure we're going to create two variables one

is called is injured and is sleeping okay so it is injured

injured Bull and uh let is sleeping in here Boolean all right and

then we go ahead and we want to create two functions a bark function and a run

function so let's say funk Funk bark and Funk and we say run now

inside the logic of this dog structure we're gonna say okay we're gonna bark

like this but we're only gonna bark if we're not sleeping

all right so we're saying if is sleeping like this then we want to throw on air

so let's go ahead and Define the error for that so we say Ena barking errors

and we say error and in here we say cannot bark is sleeping all right then

we say if you're if if you're asked to bark and you're sleeping then we say

Throw barking hers uh cannot bark is sleeping all right otherwise we bark and

then we do something similar for this actually let's see what error we're

getting in here throw okay because this function is not marked with throws so

let's just change that to throws and we're also going to change this function

to throws okay now we're going to go ahead and create

another enumeration in here and we're going to call it uh running errors I

think let's just say enum running errors errors error and then we say case cannot

run is injured and we do the same thing in here so let

me just copy this code and put it inside run and we say if is injured okay so we

cannot run if we're injured then we say running errors cannot run is injured

otherwise we say running or run something like that okay so I think you

get the point so you cannot bark if you're sleeping or actually not you and

not me either it's the dog so the dog cannot bark if it is sleeping and it

cannot run if it is injured unfortunately okay so now that we have

those we will also go ahead and create another function and we say funk bark

and run which combines those two functions then we say try bark and try

run now what happened in here we just said try without having it do and catch

what happened is that we're inside a function that can throw and if you mark

your function as throws you can simply just try things you don't have to wrap

them inside do and can what happens is that if any of these

functions that we have inside bar can run throws then this function itself

will throw so if you call this function and you call Bark then Swift goes in

here and it says oh is it sleeping yes then it throws this error

from this function and since that that function was invoked from this function

then it will throw the error idea essentially from this function out to

the caller okay so if you have a function marked that throws inside it

you can try statements without having to wrap them inside doing catch in some

rare cases you actually want to wrap them inside doing catch because perhaps

let's say that your back-end developers tell you that hey if someone calls this

function and this particular function throws an error then I want you to

actually send an API request to the back end to log that error because that

should never happen for instance okay so then you can say do okay try and then

you say catch and in here you'll do your API

okay you do your API call all right and then you can actually rethrow this error

as well so and we probably will talk about that soon as well

but just know that inside a throwing function you can try your statements

without having to wrap them with that within do and catch okay so let's go

ahead and create a little dog in here that unfortunately is both sleeping and

injured so we say dog it's an instance of dog which is injured and it's also

sleeping all right then we go ahead and we create a do and catch Block in here

we say do and we say catch dog barking errors cannot bark and also we want to

catch dog sleeping errors actually what did we

have running here sorry running errors and cannot run is injured okay so you

can see how we're catching both of these errors at the same time just using a

comma and we'll also have a catch all in here so we say cannot uh bark is

sleeping or cannot run is injured all right and in cash we say

some other error and inside do we're going to say try dog

dot bark and run all right so you can see now when we do

that we say we get this catch statement here that says cannot bark is sleeping

or cannot run is injured because we've basically caught both of these Earths in

the same Clause all right you can separate them if you want to just using

separate try statements now if you go and change these to false you will see

that none of those errors will be thrown meaning that we will just not see

anything in here basically so we can say dog just to confirm that this try

statement actually ran its course and went to the next Lifeline 115 here okay

let's revert them back in here so we have this example as well

now now in case you're catching errors in

separate catch statements just know that only the first Throne error will be

caught all right so in here we caught both of them but again Swift called this

block not because both these errors happened but it called this block

because one at least one of these happened because remember when a

function throws the execution of that function completely stops so barking

throws an error Swift doesn't even go to running meaning that this uh this error

will never be thrown therefore only the bark a function will throw its error

which is right here Swift just completely stops the execution of this

function and will run I will basically run its course out of it a step out of

that function this error will be thrown and then we will come in here okay and

we can actually test that let's copy this code and paste it in here

and then we're going to go ahead and separate these catch statements and we

go in here and we say catch first cannot bark is sleeping and when you say cannot

bark as a sleeping then we will say catch dog dot uh

running errors cannot run is injured and we say

cannot run as injured like this and you'll see now only at the first

error that was thrown will be caught which is cannot bark as a sleeping even

though and this dog is both injured and is sleeping but the Run function will

never be caught inside the bark and run function simply because bark through an

error breaking the entire function call basically in here okay so that's how you

can actually understand how you can catch verse and I hope now you know

basically the flow of when errors are caught and that you shouldn't really

expect to be able to catch multiple errors at the in the same do statement

basically all right now let's talk about rethrows I said

that we're probably going to talk about rethrows but I think it is time and now

to talk about it so when we talk about rethrows we're talking about a function

that internally calls another function which can also throw so let me just

share an example let's create a function here called full name okay and we take

in a first name which is an optional string and then we say a last name which

is also an optional string and we say okay we ourselves cannot calculate the

the full name we actually need a function that can't do that for us

inside this function so this poor little function can't really do anything it

just takes the first name and last name and calculates the full name now this ER

is really stupid and I mean it is really not how you probably want to do your uh

write your sift code but it is just here for the purpose of demonstration because

if we didn't do a simple function like this and which looks dumb it would have

to go ahead and create a very complicated function which indeed is

production ready and you would probably use it in production code but this is a

little bit easier at least to get into what rethrows keyword means in Swift so

please just bear bear with me so we say we have a function that actually does

the calculation we call it calculator it takes in a string and it takes two

string optional parameters and it is a throwing function so we say it actually

throws and it returns a string in return okay and then we just do this then we

create our own function body in here so all these errors are going to go away

now since this function is going to call this function it has to do a try right

because this function throws therefore this function should also throw so then

we say throws all right and also produces an optional

string then okay we say try calculator and in here we have to pass the first

name and last name so we say first name and last name all right so if you look

at this code you will now see okay we're trying something in here okay and our

function is called uh it's marked as a throws anyone looking at this function

will think that somewhere inside this function we're probably throwing a

specific error like we're actually um have some errors that we know what

they are and we're throwing them perhaps okay however there is another syntax for

this and it is called rethrows and how this really works is that it this tells

Swift that this function in itself doesn't throw anything it is gonna

basically invoke some other functions that throw all right so we could have

gone in here inside the bark and run function and say this rethrows okay and

you can see that our code will let's actually see what happened must take a

throwing function argument and this is is really good we're seeing this I mean

this is a example and why we actually didn't mark this as free throws so in

order I mean the error is a little bit cryptic but what it is telling us really

is that if for a function to be able to be marked as a rethrows it has to it has

to have an argument that is a closure which throws and it should call that

argument and since this bar can run function it doesn't have any argument

that is a closure it doesn't even have any arguments that it cannot be marked

as rethrows okay and that's what that error was telling us however this new

function that we have in here has an argument that throws and we're actually

calling it using try and therefore we can Mark our function as rethrows and

this tells Swift that this function in itself is just calling an argument which

is a closure which in itself throws on her okay so it's just a way of telling

Swift that hey we have a throwing function in here and we're calling it

and just we re-throw the errors that this function might eventually produce

okay so let's then go ahead and create an enum in here and then we say enum

oops enum and name errors and it's a it conforms to the error

protocol in here and we say case first name

is invalid and case last name is invalid all right then we create a

function that can produce a a full name based on a first name and last name so

we say func Plus it's an operator then we say first name

is optional string in here then we say last name as well as an optional string

and we produce a an optional string in return okay like this and we also can

throw all right good and you can see we created this

function with first name optional last name optional and result optional as

well and throws and this function signature matches this you see optional

string optional string throws at returns an optional string and the reason we

created this function is simply because we want to call this function and

instead of the calculator we're going to pass a reference to this plus operator

in here okay so let's say we want to ensure that both

um both the first name and last name are presented so we say guardlet

first name so we ensure that first name is available and we say in case the

first name is

empty okay so the way you should read the statement

is that we say make sure first name is available and make sure first name is

not empty otherwise this is how I usually read my card statements okay

make sure something and something otherwise which is the sales do this

throw name errors first name is invalid alright so if first name is nil or that

it is empty then we throw this error then we're going to do something similar

like this then we say guard let last name ensure last name is present and

that it is not empty otherwise say last name is invalid so you throw that error

and if everything then goes fine then we say return and that first name and last

name and you see these variables in here are not optional anymore and that is

simply because we're doing a card let okay after gartlett is executed I mean

if last name is nil then you never get here and that's why Swift knows that if

you did get here and it means that you've already checked that last name

was not nil therefore the data type for last name is not an optional string

anymore it is actually a string same thing with first name it is string and

not an optional string okay now that we have those we can go ahead

and try to invoke this function right here which is full name so we go ahead

and say we create a do Block in here and we say let Foo bar is try get the full

name and we say first name let's say first

name we say nil last name is nil and for the calculator we pass a reference to

our plus operator in here okay and then we say we have to catch some errors in

here so let's say catch and we say name errors first name is invalid then we say

first name is invalid then we say cash also namers last name

is invalid last name is invalid like that and then we will also have a

catch-all block in here we say catch let err for instance and we say some other

error and that is equal to err okay and you can also put parenthesis around this

as well but this this is completely optional I think actually this is a

little bit cleaner to read so now you can see that we're getting first name is

invalid thrown in here okay and that is simply because our code just came in

here I was like can I unwrap first name is there a value in it nope then it

throws this error so it doesn't even go here and it doesn't it definitely

doesn't go in these cases either okay so let's change this let's change the first

name to Foo and you will see that your error will be the other one which is

last name is invalid and then you say last name is bar then all of a sudden

your function is gonna produce Foo bar for you okay so let's let's go ahead and

do one more test and in here you can see that our function which is this operator

is marked as throws but it is still returning an optional string however

internally it never returns nil it either throws which is caught by this

guy or not caught by it is covered by the sky

or it actually returns a valid string so why is it marked with returning an

optional string and this is actually a really good good

question it doesn't necessarily have to be an optional string it is better that

it is not and it still matches inside this function signature so because this

is a promotion the a strain is not optional is a promotion of an optional

string so it can always match it but if the emotion will never match inside a

function signature okay so you can if if this requires a string you can never use

a function that returns an optional string you will actually get an error

now or we should get an error there we go okay so just remember a promotion

will work but a demotion won't and this is a promotion we're saying that

although you need an optional string which is at a lower level meaning that

it can be nil but we will always produce a string which is at a higher level

meaning it's never optional so it is a promotion a promotion function

signatures in Swift always works okay good we've now talk about that now let's

also talk about results and results are also very important to understand

they're kind of related to error handling so that's why I wanted to name

them and they're usually useful when you're writing API calls okay so what we

want to achieve in here is to create a function that is called get previous

positive integer and you will pass an integer to this function and the res and

the responsibility of this function we're going to develop is to find the

positive integer right before the integer that you pass to it as an

argument so if you pass two this function is going to have to return the

value of one if you pass one this function has to return zero but what

happens if you pass zero there is no more positive integer before zero

because the next number if you do a minus one to Z basically say zero minus

one you are going to end up with minus one and that's not a positive integer so

you could say well let's just throw an error and you'd be right you could just

Mark your function as throws but there is another way of doing that there is

another way of saying that a function fails but it fails perhaps a little bit

more gracefully it doesn't actually throw an error but it carries an error

with it okay and this concept is also available in many other programming

languages you have it in Dart you have it in Python you have it in Rust so many

other programming languages have this concept and in some languages it is

called either but in Rust sorry in Swift it is called results so let's first go

ahead and Define our error so we say enum integer

integer errors it is an error and then we say case no positive integer before

this value okay enum error case did I do something

incorrectly in here it doesn't look like it formatted it right but this is fine

okay then we create our function we say func and we say get previous V is

positive integer and we say from int all right and in here what we need to do we

are not going to say that this function throws but instead we're going to say

that this returns a result that is either an integer or an integer error

like in here okay so now all of a sudden instead of this function just saying I

throw anything you're saying it either gives you the result or it gives you an

error of this specific type which is a little bit cleaner to be honest with you

because a throwing function doesn't necessarily specify or it can't really

specify the type of errors that it throws so the color the call side to

that function always has to have a catch-all block in order to understand

okay what error is actually being thrown by this function but by using a result

you specifically say which Earth you're gonna throw not really throw but which

Earth you're going to carry with you if any all right

so let's guard that this integer is more than zero otherwise we say return a

result that is a failure and its failure is indeed an integer error you can see

in here that is no positive integer before this value and the value is this

integer right here okay so regarding that the ins is more than

uh zero basically because otherwise we can't minus one all right then after

this we say okay in that case we wanna in any other case where the integer is

more than zero then we have to return a successful result and we say return a

result with success and the value is integer minus one

all right so you see how this function is structured at the moment okay then we

go ahead and create a create another function which internally calls this

function so we call it funk perform get and this

is just to add another layer of complexity really to our code so that we

don't go ahead and directly call this function I just want to show you how you

can call this function within another function okay so we say perform a get

for a value and we say value as an INT and inside this function we're going to

call the other one get previous value sorry get previous positive integer from

value and then since this guy returns a result and if you look at results you

can see just like optional result is an enumeration meaning that you can switch

on it so let's switch on this guy and we say in case if we get a success and we

say previous value all right uh actually success previous

value maybe not previous value previous

positive yet previous value then we say previous value is previous value but in

case we get an error we say case failure and we say error then you can say okay

but this error it is in itself an enum it is an integer errors enum we already

know that so since it's an enum you can have another switch within your switch

the first switch is switching on this result

and since it gets the error which is of type integer errors with it itself is an

enum then you can have another switch in here then you say switch error in the

case of no positive integer you put a let in here and you say this value

then they say no positive integer before this value all right

so now that we have this extra logic in here we can go ahead and call our

perform gets function so I'm just going to copy paste some code in here you can

see first we pass 0 to this function and let me comment this line out

we first we pass 0 and 0 then count so that zero comes in here and it's then

passed into this function then it comes in here and says make sure int is more

than zero oops it's not return the failure

and then it comes in here into failure gets the error we switch the error is it

no positive integer before yes it is indeed and then you get this line

printed to the console no positive integer before zero and that's correct

okay then we bring this go code back you can see now it will hit this block and

it says previous value is one all right because the previous value before 2 is

indeed one so that's short and sweet about error handling in so if you can

either use throwing functions and throwing Constructors for instance and

then do and catch and you also looked at try with a question mark which

optionally tries a function or try with an exclamation mark we should try to

always avoid actually because it can crash your application and then at the

end we looked at how result also works in Swift and how it it goes hand in hand

with error handling in Swift as well okay

now that we're done with error handling in Swift let's talk about Collections

and collections is something we've talked about up to this point a good

maybe five or ten times and the five to ten times I would say but we haven't

really gone into details about them so I'm gonna close this playground in here

I'm going to press command n and say blank in here and let's create a new

playground and we're going to call it collections all right and ensure that

it's created in your main workspace and then we say create

and just like normal we say import foundation and run this playground also

automatically we get rid of our Explorer here and then we can start talking about

collections so collections as their name indicates there are a collection of

stuff all right so for instance with numbers and if you're I mean not if but

since you're already familiar with other programming languages collections are

also called arrays or dictionaries or even Json objects for instance if you're

working with simple JavaScript you can just say

const something is equal to and then you add your values in here value blah okay

so this is a simple Json JavaScript and it's some sort of a collection and in

Swift you also have different types of collections one of them is an array so

you say let's numbers is one two three four for instance and then you can do

different things with this collection you can say give me the first value give

me the last value give me the count of objects in here or you can say numbers

map every element to its minus counterpart so you can see in here then

let me just bring this over so you can see we have one key one two three four

then the first element is one last one is four there are four elements total

and then here we mapped every element inside this numbers array to its minus

counterpart okay so this is an operator in here now if you have an array in

Swift you can also mutate it as long as it is a variable so let's say VAR

mutating numbers and we say 0 1 and 2 and then you can see mutating numbers

append the value of three and then mutating numbers

insert the value of -1 at the index of zero okay so index of zero is right here

not that the zero is actually let's let's just say four five and six instead

okay and then we append the value of seven and we then insert the value of

three at the index of zero meaning that the array was four five six but at the

end it will be three four five six seven you see what happened in here the index

of zero is right here and in the index of one is right here index of two is

right here because the in index is in arrays and any collection in pretty much

every program language that I know about they start at the index of zero they're

called zero based indexes okay so and apart from doing a pens and

inserts you can also insert a whole array inside an array so you can say

mutating numbers insert and then you can say insert the contents of for instance

one and two at the index of zero so let's see what happens in here

and then right it's not insert it is actually insert contents off so this API

calls called insert contents off and you can see the resulting array will be one

two three four five six and seven here okay you can enumerate over the elements

inside an array by just using a for statement for Value in numbers so then

you can say a value and print it to the console and now

um playgrounds have an interesting way of showing values over time since we're

animating over these values and there are four of them it can't print them all

in the same line so you have to click here I believe and it gives you like a

little graph and then you have to right click on it and you say value history

then you get the values one two three four otherwise it shows you a graph for

some reason okay and let's somehow remove this okay there we go so that's

how you would go through values inside an array okay

you can also enumerate through items inside an array with pattern matching

using the where Clause so if you want to for instance grab all the uh all the

even numbers inside this array so because you saw this printed one two

three and four and one and three are not even numbers but if you want to grab

only the even numbers you could say four value in numbers where

value and we're basically the the result of

dividing the value by 2 should be equal to zero okay so this is how you would do

your pattern matching if you say value in here we can do the same thing that we

did earlier and say value history and then you only get the values of 2 and 4

in here okay so that's how you can have a where Clause right after your four

statements now you can also map objects inside an

array and mapping is also very important because it's one of the most useful

functionalities of collections mapping means that you take the values inside

that collection and you turn them into something completely different if you

want to okay so let's say numbers you map them you see and it says okay I give

you the number so let's say value and in here you can say I return anything in

this case we've decided to return an integer and we say value multiplied by

two now you can all of a sudden see that numbers are 2 4 6 and 8 whereas they

were originally one two three and four so here you multiply them by by two

however inside map you can't return anything you can say I actually return a

stream okay and then you turn these into a string you can string first multiply

them by two but then turn them into a string now you can see there are strings

so map allows you to map it to anything all right and now that we're talking

about mapping it to anything you can you can guess that this map is indeed a

generic function because it allows you to change the resolved value and if you

look at its signature you can see it in is it indeed giving you the elements

inside the array but it allows you to throw to return anything and the result

would be the array of that anything okay so if I go and say let values you can

see values is an array of um not in this case but in this case values will be an

array of string okay like this so values is an array of string right

now and just a note about this at Maps don't necessarily have to be this

complicated I mean um to me this and actually we can recommend this syntax

more than I can recommend the next syntax I'm going to show you and simply

because the more information you give to the Swift compiler the faster your code

compiles in larger applications but if you have very simple applications you

don't have to do this much syntax work in Swift you could literally just say

okay first of all I don't want to give you I don't want to tell you what return

value I have and Swift still is happy with that you can also remove this in

here because Swift already knows the value is an integer okay and this works

as well and you can completely remove that and instead of value use dollar

zero and that works as well so your code could pretty much just look like this

but again I mean this does work but it is it has a very little information

about what that code is actually doing internally so so a new newbie software

developer may be quite confused by it and also as I said this is more

information to the compiler which allows it to compile your complicated codes in

the future a little bit faster as well okay

apart from mapping arrays you can also filter them meaning that you want to

grab specific values out of this array you could say numbers

then you filter and you say you get the value and you turn and return a Boolean

and for all the objects that have to be included in the result of this filter

function so you say if the value is greater than or equal to 3 then it

should be returned from the result and you can see the result is 3 and 4. okay

so that's how Filter Works you can also do compact mapping and compact mapping

mapping is similar to map but it returns an optional and the values that are

returned from this compact map which are nil will not be included in the results

so it's a compact map is a combination of map and filter okay so let's have a

look at that we say numbers compact map and we say we get the value as an

integer and we return a string okay an optional string remember it should be

optional optionality indicates a filtering so if it is nil it won't be

included in the resulting array then we say if Val value is divisible by 2. then

return the string of that value otherwise return nil so let's break it

down into separate lines it's a little bit more readable okay so you can now

see the result is at Raf strings that only includes two and four but it

doesn't include three and one or one and three basically okay so compact map when

you see it just know that is a is a combination of map and filter at the

same times arrays in Swift can also contain the

value of nil so let's say numbers uh numbers numbers two and it is an array

of optional integers so meaning that it can contain not just integers but also

nil then you can say one two and then nil four and five so this is completely

fine all right and then if you say numbers two dot count you will actually

see it is five because nil is one of the elements one

of the valid elements inside this array and if you want to grab all the values

inside this numbers array and that are not nil then you would say let's not

snails is equal to numbers 2 filter so you

basically say here's my integer and I return a Boolean for all the values that

are not known then you could say um let's say its value its name is value

then we say value shouldn't be nil like this all right and you can see the

result of this is just one two four five all right however however

this you will be like okay we've checked that the values are not nil and we place

them inside this array so this array should now be an array of integers but

that's not correct because if you look at this is is still an array of optional

integers so what's happening here is that though we checked for nail values

but we didn't tell and this so basically filter doesn't allow you to change the

data type all right you can see it always returns the same array of the

same element type so if our elements is optional integer the result of this

function will indeed be integers as well in order to grab the non-null or not nil

values out of this array and also change the data type you have to use compact

map all right so um so you could say in here not Nails is

numbers too and we say compact map and we say we take the integer

and which is value and we actually return an optional integer as well and

just return the same value all right if this value is nil it won't be included

in the result and also it won't basically change the data type so not

Nils is now not an array of optional integers okay I know it's complicated

and it's a lot of generic code but it really requires that you work with these

functions yourself to for it to basically click

now arrays can also include instances of the same object multiple times so if you

say numbers three and we say one two one two you can see that numbers three dot

count is indeed four so it contains four objects it doesn't check whether there

are unique or not okay arrays can also they don't necessarily have to include

home homogeneous objects so they can be heterogeneous meaning that you can have

integers and strings uh mixed up and Blended up in the same array so let's

say let's stuff one and we say it is an array of it has an integer of one then

it has hello then it has an integer of two and has a string up world but this

will give us an error or it should because it says it is not a homogeneous

array all right and it says it's a heterogeneous so in order to fix this

you can see Swift is telling you to actually add as any to the end of this

array and a collection literally could only be what is the same

as an array of any and I mean this to me looks fine

uh but I'm sure I'm not sure really what is the same collation level It could

only be inferred to any add explicit type annotation

um I believe we've already done that so I'm not really sure what it is

complaining about let's just say stuff one and see if Swift has understood what

this code is actually doing expected separator did I miss a

separator somewhere let's stuff one to me this looks fine but not sure

really what it is complaining about let me just bring it in here and then we say

hello let's put all of these in oh because I've missed a comma in here I

can see okay sorry about that so I've missed a

comment there so now you can see our array looks fine and if I say stuff one

count it should include the count of four in here okay there are four objects

so this is a trick to get your array to include heterogeneous objects as well

all right so um we can also go ahead and change the

Syntax for this so if I copy this and paste it in here and changes the stuff

too and then stuff to account if you don't want to have this as in here you

can also tell Swift that this is in fact an array of any by doing this column in

here just specifying the data type right there okay so that's another way of

actually achieving the same result now that we've talked enough about

arrays let's talk about uh sets a set is a special object it's a special

collection that only contains unique values all right and the way it

calculates uh uniqueness is based on hash values and equality all right and

this is a little bit complicated a lot of people think it's just hash value but

it is not it's also equality which is very important to understand and what

sets so let's create a set we say unique numbers and then we say it is a set of

the values one two one two and three all right and then we say unique numbers

count and then unique numbers map them to their minus values let's just see

what values we get in here you see after the creation of this set the set only

includes the values of three one and two so two things are quite interesting

about this is that it removed the duplicates so both twos were not

included only one instance was included it and the same thing with the value of

one only one instance was included so that's one thing that's interesting

about creation of this set or and one of the properties that's important about

sets it only includes unique numbers and the other one is that this array that we

just passed to it it's ordering was completely changed within the set so

sets in Swift cannot guarantee ordering as you pass the ordering to it so the

ordering could just be mishmashed and the set will order the items as it

pleases all right so

sets can also contain Nils so we can go ahead in here just like arrays so let's

say my numbers is a set of one two three and nil and five and then we say let's

not nil numbers if we want to get the not nil numbers then we say it is a set

of my numbers and then we compact map this guy a compact map and we grab only

the current value you can see in here compact mapping let's actually break it

down into separate lines so it is more readable like this and

like this all right so we're just taking the same values which are inside my

numbers returning returning them from compact map compact map what it does is

if the values are nailed it removes them from their result and you can see the

result of compact map inside a set it is an array of the values and that is the

reason we're putting it inside another set because we want the return value to

be a set as well all right and then we say not nil numbers

in here you can see in here we have five where is it uh two three nil one five

but in in there we have only three two one and five so nil was removed

essentially by calling compact map on that sets okay

now you can also create heterogeneous sets just like you can create

heterogeneous arrays so a set doesn't necessarily have to only have integers

for instance so the trick to do that is to create a set of a protocol called any

hashable all right so you say stuff three for instance and we say this is a

set of any hashable and you can look at the code for any hash well sorry it's

not a protocol it's a structure and we say it is equal to uh one two three and

then bounded all right then we can say stuff three count you will see that

includes four values all right so this is the trick to create a

heterogeneous sets as well now if you want to extract specific

items uh like of specific types out of uh any of these sets or arrays and let's

just focus on the sets right now actually let's have a look at our stuff

one you can see our stuff one is an array at the moment and that is an array

of any but if you want to grab specific objects out of this array which are of

specific types for instance only the strings or only the integers you can use

a keyword which is called as so let's say let's ins in stuff one and again

remember stuff one is this array it has integers and strings and you only want

to grab the integers out of them so then you could say ins in stuff one is stuff

one and then you compact map all right remember compact map does map and filter

at the same time then you get your value which is any and you want to optionally

return an integer then you say value as ins so you compare the values type to

an integer and optionally return it if it is integer okay

and then you can see in here that the result of this is only your integers

and you can do the same thing with strings so you can say okay let's copy

this and then we say strings in stuff one and then you get the value and you

optionally return a string and then you say as long as the data type is a string

I return it okay then you get the hello world printed in here okay

so if you if you are comfortable doing this with a race then you're probably

also comfortable doing that with sets and it is very similar it's actually

compact map on sets as well so let's copy this code ins in stuff one and then

we say ins in stuff three and remember stuff three is a set then we go in here

and we say stuff three and we compact map and the value is any hashable

hashable and then we optionally return an INT and then we get the result

printed to the screen which is two three one and you can see one two three van

dot so van dot was essentially removed from this set but one thing to note

about this is that as I mentioned before compact mapping on a set doesn't return

a set it actually returns an array so if you go in here and call type of which is

an internal function in Swift and say give me the type of ins in stuff three

it will tell you that this hopefully is did it crash it will tell you it's an

array it's not a set anymore though stuff 3 was a set uh you can see in here

is a set but the result of compact mapping is set is an array okay so just

keep that in mind now now that we talked about sets a

little bit and we talked about that they can contain the only that they only

contain uh unique objects then the question is how does it calculate

uniqueness and and the way it does it is using a protocol called hashable

now hashable a lot of people think that only thing it does it it contains a some

sort of a hash value is some sort of an integer value that uniquely identifies

every object but it but hashable protocol

in itself also includes equality all right so uh without without actually me

talking too much about that let's have a look at an example so let's just say we

create a person struct in here struck person and then we say we have an

ID so every person has an identifier we have a name of string and then we have

an H of integer as well okay and then we want this person to be

able to instances of this person to be able to be included inside sets Okay so

without making and without making this person hashable let me show you what

will happen if it is not hashable and you try to create a set out of it so

let's say that we have a foo ID in here and we say it is a uuid then we say let

Foo is a person with the ID of Foo ID its name is Foo

and its age is 20. all right then we create a bar person in here and we say

bar is pretty much similar to Foo and we say bar but we forget to change the ID

and bar is also using the foo ID its name is bar and its age is 30. all right

now we want to go ahead and create a set of Foo and bar so let's say we have

people and we say it is a set of person and it

is equal to Foo mbar now we should get an error ideally from Swift telling us

that these objects are not hashable you can see it says it does not conform to

protocol hashable all right so how do we do that how do we ensure that they

conform to hashable so let's go ahead and say that they conform to Hash Rule

and everything will just go fine nothing will happen in here you won't get any

errors okay and if you go in here and say people that count

let's go in here okay you will see unfortunately it is still two so what

happening here we said that well we are making this person hashable and it

should ideally not be placed twice in this set because uh it is pretty much

the same but if you look I mean same data but what happens in here is two

things when you when you create a structure and you just say it is

hashable without having any custom logic in it meaning that you didn't actually

tell Swift how to calculate the uniqueness of this object what Swift

does is that it looks at all the properties of that object and says okay

are all these properties unique themselves like are they hashable and if

you look at uuid is indeed hashable if you look at string it is hashable

uh let's see extension string hashable

somewhere it should have been made hashable I'm not sure if it is exactly

there we go extension string hashable and also if you look at the code for INT

it should also be extension and hashable there we go so since all these

three are hashable then Swift says okay I'm gonna calculate the hash value

myself then it says okay you created a person it has the ID let's just say it's

hash value is one let's say then it says oh the name is Foo the hash value is for

instance 10. I'm just making this up okay and the hash value for this guy

let's say is 20. all right then it comes to bar and says oh it has the same ID as

the other ones which is has a hash value of one but it's its name is bar so its

hash value is let's just say 30. and the age is also 30 with a hash value of 40

for instance okay so it says okay then you put both of these inside a set and

I'm gonna calculate these hashes 20 plus 10 plus one for instance okay this is

not how hashes are actually calculated but we're just going to plus them

together so 20 10 and 1 are going to be 31 and then we have 40 30 and one which

is going to be 70 a month so at 31 and 71 are not the same meaning that they're

basically not the same object and should both be placed inside the sets Okay so

that's how hashing basically Works within Swift okay

but what we may want to do is to tell Swift that hey we actually don't want

people with the same ID to be recognized as different people so what we want to

tell Swift is that if two people have the same ID then they're essentially the

same person okay and in order to give Swift more information about how it

should do our hashing we should go ahead and basically implement the hash

functionality somehow ourselves or at least inject our own logic within it so

let's create a person two object in here so a person to structure so now that

we've seen that example let's say a struct person two okay and we're gonna

grab let's actually grab this struct from here but instead we're just going

to call it person two so person two in here and we said that

it is hashable now if you make an object hashable you also have the ability to

override a function in here and not really override but also Implement

actually a function called hash into all right and this function comes in here

because we have we've conformed to the hashable protocol all right then in here

what you can do is to say hasher and then you combine you call the combine

function on it and then you basically hash the fields that you want to be

taken into account while Swift does its hashing so what this really did in here

is that it jumped over hashing name and age and instead only hashed ID within

the hashing mechanism of Swift all right so now that you've done that you also

need to tell Swift whether two objects are Equitable because you've just

implemented your own hashing functionality

and when you say something is hashable by default it's also Equitable and what

happens in here is that right now you set that take ID only into hashing

mechanism but in terms of equation because hashing is also doing equality

Swift if you don't intervene Swift goes and it says okay the hash values are the

same but these two objects are not really equal because by default Swift is

going to also equate all three properties so in here what we're going

to do is to say static func equality so we're going to overwrite equality as

well on the left hand side we say self and the right hand side itself then we

say Boolean and we say as long as the left hand side's ID is equal to the

right hand size ID then these two objects are equal so not only have we

changed the way a hashing works but we also need to change the way equality

Works otherwise they won't really come to an agreement with each other

okay now that we have that let's go ahead and

create a baz ID in here and we say it's a uuid all right

and then we say we create a baz person in here which is person two remember

create an object of type person two not person then we say baz ID its name is

bass and then we say it has or he has the age of 20 or she has the age of 20.

then we create a Cox value in here and we say q u x and we say person two and

then we say baz ID and the name is Cox and the age is 30. all right so you can

see now the ID is the same but all the other values are different however the

way we've done our hashing and equality is that we only take into account the ID

so even if their names are different but they're using the same ID then we

consider them to be the same person and that's why you can go in here it's say

if that's equal to Cox they are equal so this basically is invoking our equality

and you can see it comes in here okay but that's not the point that's not what

we're trying to do in here we actually want to add them to a set so let's say

let lets people people to and we create a set of bars and Cox in here and if you

look at the values inside people too it should just be one value

people too that count all right simply because our hashing intervene in here

and both these objects were considered to be the same object all right and if

you take the first item out of this you can get a person person two and then you

can say the first objects uh name give us the name all right and you can see it

is pass all right so a Cox was not inserted into our set simply because baz

was already there and Cox was considered to be the same object therefore it was

not inserted into the set all right so that's how you can go ahead and

Implement your own hashing value or hash value and equality all right that's

enough about sets let's talk now about dictionaries now dictionaries they're

also called Json objects and many other programming languages like like as such

as um not really Json objects yeah well kind of Json objects yeah there there

are keys and values basically okay and you define them using a square bracket

in um in Swift so you say user info and you

can create your dictionary and then you say keys are in this case string for

instance with a column and you separate the keys from the values using a column

and you can say the key is name the value is Foo this key is H and oops if

we can spell H and its value is 20 then you can say I have an address field in

here whose value is indeed another dictionary and you can say the address

has a line one and it is address line one then we have a postcode for instance

it's key as postcode and its value is one two three four five let's say all

right and this is completely valid a swift object if I haven't messed

anything up let's see Foo age address all right and we also have to tell Swift

that you can see it is a heterogeneous values because some values are strings

and some values are integers then we have to tell if there is a dictionary

with keys equal to string and values of any type all right without that it won't

work however if you didn't have this age in

here and we didn't have this address in here we could have just gone away by

defining our dictionary like this as Swift would have understood the data

type to be of key strings and values of strings as well but since we have keys

of string and value of integer and a key of string and a value of a dictionary

then we have to tell Swift that the keys are string and values could be anything

basically now you can grab values out of your dictionaries using type using

subscripting so you say user info grab the name and you can see it will give

you the value of Foo in here you can say give me the age user info give me the H

so you're basically giving it the keys and you're extracting the values for

those keys now you can say user info and then give me the address let's go in

here address at rest all right and since this is an

address dictionary coming back from here you may be hoping that okay since this

is an entire dictionary maybe I can type a key in here as well and get the

postcode all right and if you do this then you get an error because you've

told Swift that the values that come out of this uh dictionary are of type any

meaning that Swift Just believes that this is any and now you're trying to

tell Swift that this is not any and it's in fact a dictionary and it should go

into that dictionary and x and extract a value with a specific key and Swift Just

rejects that okay there's a dangerous way of doing that forcing Swift to

believe that this in itself is a dictionary and that is using the as

syntax but please don't ever do this in production applications and there there

are better ways of doing this so I just want to show you how it works you can

say get the address and force cast it to a dictionary of

type string and string you can see it because this has keys of string and

values of type string as well okay so after doing that uh then you can go

ahead and say give me the postcode on it all right and this should this should

work but in production applications really is not a good idea to do this so

let's see what happened actually found nil one on wrapping optional value and I

think it's because I I misspelled address basically

so it works but you should never do this because this will crash your application

should this key Either not exist or that its value shouldn't be of type string or

string your application will crash so please don't do this I'm just showing

you so that you know this syntax also exists okay if you want to extract the

keys and values out of a dictionary you can say user info dot keys and also you

can say userinfo.values and this will give these this will give you the keys

only you can see in here let's go in here the keys are age address name and

the values are 20. let's go here 20. Foo uh which is let's see where it is

it is 20. Foo and then this dictionary so you grab

basically only the keys or only the values out of your dictionary using that

syntax however it is more common that instead of just saying keys and values

you want to enumerate over the keys and values and their Associated values you

can because you can see in here we're only saying keys and only values but

what if you want to grab every key and its Associated value the Syntax for it

is for key and value in user info then you can print them out

key and value like this okay let's see if the playground can help us extract

these values so and the key says name value history you can see age address

and name are the keys and the values we can also perhaps get their history let's

see value it's oh the playground isn't so smart in

being able to print the value so let's instead print the values and see

if we can get them in the console uh like this so here are the values

basically okay and you can also print the keys as well so let's say we print

the keys and we print the value so uh the key of address has this value the

key of name has this full value and the key of H has the value of 20. all right

so we can do that as well let's just revert them back to how they work okay

now you can also have a where clause in your enumeration over keys and values so

let's say four key and value in user info where the value is an integer okay

and then you can say key and value so you see the only value that was an

integer had the key of H and it the value was of course the value of 20. all

right now you can also have multiple word Clauses so you're not

limited to only one where Clause so you can say four key and value and use for

info were the value is an INT and a key that

counts so the key is a string and we're saying it should contain only two uh

more than two characters then we say give us the key and the value all right

so the count is pretty much the length of the of the key

and then you can see that we got the same result because age is three letters

long and are conditions that it should be more than two but if in here we said

more than three then this will never be cost so we won't get any results in here

okay so I think that's actually quite enough right now about collections we

talked about arrays we talked about sets and we talked about also dictionaries

and some new formats and pattern matchings that you can do with these

collections they're very very useful and I think you need to really get and get

quite handy with these objects yourselves and in order to get a good

grasp of how they work I can just sit here and explain these for ages but

without practice and probably it will never really click so my advice is to go

ahead and create some sets arrays and dictionaries yourselves to get a good

grasp of how they work now that we talked about collections it

is good time that we start talking about equality and hashing as well I mean we

did touch upon this topic a little bit right now but we haven't fully covered

them equality and hashing they're like their own whole world of understanding

how they truly work and basically understanding them is the key to

understanding how sets for instance work and how equation generally in Swift

works and so I think it's very important that we dedicate it's

um a whole section just to equality and hashing so and that's what we're gonna

do right now so I'll see you there let's then go ahead and create a separate

playground for this so we say um blank and foreground sorry playground

and we say equality and hashing like this and ensure that

you're creating it in The Roots folder like this and then we just say create

and we import Foundation and we can get rid of the Explorer to

the left hand side now equality in Swift is provided using a protocol called

e-codable any object that conforms to the equilible protocol has to have a

function a static function and which is an equality function like this is pretty

much an operator and this function has to have two arguments one at left hand

side and right hand side both of the same exact type as the current

structural class implementing it now if you go ahead and create a person

structure in here and say that this person is conforming to the equatable

protocol and you say let's ID is a string and then you say let's name is a

string then we create two instances of this we

say let's Foo one is a person with the ID of one all right and then we say name

here is Foo then we create food too right here and we say the name is

actually bar then if you say if Fu one Foo one is equal to Food 2 then we say

they are equal with an exclamation mark in here because they shouldn't be they

are not equal otherwise okay so what happens in here is that by ensuring that

this person is Equitable all right let's also make sure that this is running

automatically by conforming the struct a person to Equitable as Swift goes in

through all the properties of the structure and ensures that they are

indeed themselves Equitable string by default conforms to the Equitable

protocol and so does this one so then Swift says okay then I understand that

it should be Equitable however if you go in here and say a struck dog and don't

make it Equitable and in hear you say this person should also have a dog all

of a sudden Swift will throw an error in here saying that oh I can't give you

equal Equitable by default because dog which is one of the properties of this

person's structure does not conform to Equitable if you want to get rid of this

just ensure that this dog is also Equitable which then gets rid of the

problem in here but the only problem we have in here that is that we need to

pass a dog instance in here but we're gonna remove all this dog reference in

here just wanted to show you how default implementation of Equitable basically

works it looks at all the properties and then make sure that they're Equitable

and then goes through all of them one by one compares the properties between

these two objects that we're comparing okay

now you can also override equality and uh you can basically say let's say that

you in your person uh structure you want to say any two persons that have the

same identifier should be considered equal so then you can say extension

person and you can see at the moment these two

objects right now before our extension they're marked as not equal all right

simply because their names are not equal but if you go to extension person and

then Define the static function equal equal like this and you say left hand

side itself like this and right hand side itself as

well and this function should return a Boolean indicating whether the two

objects are equal or not then we say if the left hand side's ID is equal to

right hand size ID then these two should be considered equal now all of a sudden

you see that this will be flipped to they are equal

previously before this extension this branch of code was being executed

because by default there were not equal since they had different names however

with our extension in place since we're only comparing the IDS then they're

marked as equal so if you comment your code out you can see all of a sudden

that this Branch will stop being executed and instead this Branch will

get executed all right so that's how you can create your own

equality on custom objects so we can comment this guy out

apart from structures you can also Implement custom equality on

enumerations let's say that we have an enum in here we call animal type and we

have a case where a dog and we ask for the breed and also we have a cat and we

ask for the breed okay now let's say that you want to compare these

um to with each other if you go ahead and say let's dog and say is an animal

with a type of dog with its breed is a labradoodle and then you say let's

whiskers is an animal type another dog basically exactly of

the same type then if you go ahead and say if dog equal to whiskers let's just

change this to maybe dog two dog one and Dot two and then we say if

dog one equal to dog two like this you can see that you get an air from Swift

because by default animal type is not Equitable you can go ahead in here and

say okay well I'll make it Equitable does this work you'll be surprised to

see that actually my default what Swift does is it looks at these values and

says let me let's put some values in here and say they are equal

like this otherwise we say else they are not equal all right so since dogmon and

dog 2 we actually are giving them the same values in here then suit by default

says oh they're equal but if you change the value inside this breed for instance

then Swift says they're not equal so Swift does the same thing that it does

with structures as it does with enums it goes through all the properties of those

enum cases and then make sure that they're Equitable if they are it will

just call the equation function on those parameters as well and Compares them

with each other if all those they're equal to each other and the case is

equal to the other case as well then the enum cases are marked as equal however

you can go ahead and change this implementation so you can say extension

extension animal type and let's just remove the Equitable from here and we

say animal type becomes Equitable in this extension all right

and then we go ahead and Implement a an extension and sorry the static Funk left

hand side itself and right hand side itself as well and then in here we say

bull all right so now what we want to do in here is to compare the breeds with

each other so we say we switch the left hand side and the right hand side then

we say in case and we have a dog with the left hand side breed and another dog

with their right hand side breed then they're considered equal as long as

the left hand side breed is equal to right hand side breed we do the same

thing for cats so we say if we get a cat in here and a cat in here then they're

equal to each other as long as their breeds are equal and since this pattern

matching is the exact same thing between dog and cat you can see they're getting

left hand side breed right hand side Bree and the same thing in here you can

remove this coating here and just put a comma and remove this case as well all

right so they're basically doing the same thing

and then you can go ahead and say anything else they're considered not

equal to each other okay so as long as it's a dog and a dog and their breeds

are the same then it's considered to be the same and if it's a cat and a cat

then they're considered to be the same as well

so let's see what we got and we got this oh we have to return this of course we

can't just write that statement in the playground good then we can go ahead and

um basically we've now created an animal type let's go ahead and create an animal

now so we say it's struct and we say animal animal in here animal

and we said let's name is a strain and then we say let's type is an animal

type okay and since both string and animal type by this point are Equitable

you can make this animal also conform to Equitable all right however what we want

to do is to say okay the animal equality has to only look at the animal type we

don't want it to look at the animal name that is the default behavior that Swift

looks at all the properties but in this case we just want to look at the animal

type all right so let's say that then we override the static oops static Funk

equal equal and we say left hand side itself and right hand side itself as

well and we return a Boolean okay and we only look at the types so we say left

hand side type should be equal to right hand side type otherwise they're not

equal okay then we can go ahead and say let cat one

is an animal and its name is whiskers like this all right and it's animal type

is actually a cat then we say it is a cat of type Street gap of the breed

Street cow okay let's put that in here and this is also a shorthand of writing

um the animal types instead of saying animal type in here you can just say dot

cat so instead of doing this you can just do the shorthand and so it will

understand the code anyways let's copy this code and then we say cats number

two and its name is whoosh okay just like that and it's also a straight cap

so looking at our equality functionality in here we only look at Types on animal

in order to to determine if they're equal to each other or not so then we

should be able to go and say if cat1 is equal to cat2 they are equal because of

their breed actually type because of their type

else and they are not equal all right and you can see that this branch of the

code is being executed simply because our equality custom equality on animal

only compares the animal types and since they have the exact same type of cat and

Street cat then our code works and you you can actually go and remove this

implementation on animal type because this pretty much is the same thing that

Swift provides Equitable and you can see the code will be executed just like

before so no difference really so it's up to you if you want to do custom

implementation of Equitable or you want to let Swift deduce this on its own if

Swift can already deduce this on its own which it can you shouldn't really go and

write an exact same implementation so this this is pretty much just redundant

but if your custom implementation of Equitable adds some functionality to how

swift does it by default then please go ahead and add your own Equitable to your

custom types okay so we can now we've had a look at Equitable let's look add a

hashable and we've already talked about this a little bit before but let's just

talk a little bit more in details about it just like Equitable hashable also

looks at all properties of a struct or a class to make that start or class

hashable so if you say struct house and we make it hashable then we say let's

number is int and we say let number of bedrooms

is an INT then we say let house one is house with the number of one two three

and number of bedrooms is let's say two all right and then we say house one and

you can see now you have a property in here called hash value and that is

coming from the hashable protocol in here

then we go ahead and create another house we call it house number two in

here okay house two and its number is one two three but it's number of

bedrooms is three and then we print out its hash value in here as well now you

can see these hash values are different simply means that they basically if you

create a set with house one and house two they can occupy their own space and

not overwrite each other however if you go in here and say number of bedroom and

bedrooms is two then you should ideally in here see the exact same hash value

meaning that you cannot put both houses inside the same set and expect them both

to basically appear in the set one is going to overwrite the other one okay so

if we go ahead and create a setting here we say let houses is a set of house one

and house two and please note that I changed this back so it's now number of

bedrooms two and this one is three then if we say houses dot count then you can

see we get two in here because none is overwriting the other one

let's see if the playground is going to be able to update soon hopefully

even if it doesn't show the count we can still see in here that we have one house

in here and another one here and now the count is also being displayed right

there okay really good you can overwrite the uh how hashing of course Works we've

already had a look at this and when we talk about collections but let's have a

look at another example so we say a struct numbered house okay and we say it

is hashable like this and we say let's number is int

and then we say let's number of uh bedrooms is an end and this is pretty

much the copy of the house structure but we had to give it another name and

because you can't have two structures with the same name in the same code

scope in Swift okay then in here we're going to go and overwrite this a hashing

mechanism so we say hash into and we say we only want to combine the number into

the hasher so we say combine the number and this simply means that as long as

two houses have the same number then they're at the same house pretty much

when it comes to their hash values okay however this doesn't mean that they're

equal you have to override equality as well so say static Funk equal and we say

on the left hand side we get self and the right hand side we get cell self as

well then we say this returns a Boolean and

then we say as long as the numbers so we say left hand side number is should be

equal to right hand sign number and then both houses are considered to be equal

to each other in that case Okay so let's create let house three and please make

sure you create a numbered housing here not a house it's house number we say one

two three and number of bedrooms is two okay so as a house number one two three

then we create another house we call it house four in here okay like that

and then we say it is a numbered house and the exact same number as this house

however it has three bedrooms okay then we create a set of these we say houses

at three and four it is a set of house three and house four and then if you

look at houses three and four count you can see there's only one object inside

this set simply because house three and four they can only consume the same

space in our sets and simply because their hash value is the same you can see

in here and let's see if playground is going to be able to update our codes

hopefully soon if I close this one maybe it's just gone crazy a little bit

let's say automatically run hopefully it can run the code so you can

see there's only one value in here and if you say houses three and four get the

first item then it gives us a numbered house and then we can say get its house

number bedrooms and it says the number of bedrooms is two and the reason behind

this is that house Ford could not be placed in the set simply because there

was a house already in the set with the same hash value and you can also look at

the house at three hash value and house for hash values and they should pretty

much be the same simply because the hashing algorithm is only taking the

house number into account so you can say house three

house three number dot hash value and it should pretty much be unique

as well and you can see they're exactly the same thing okay and house for that

number hash value there the same as the entire hash value of the house okay

another example now EMS are by default hashable even without raw values so I'll

show you in here we say enum car part car parts like this and we say case a

roof uh case tire and case trunk then in here we say let's unique Parts

is a set of car parts okay and it's equal to a set that contains a

roof it contains Tire

it contains another roof and then a trunk so since this is a set of car

parts and it doesn't have any raw values like we're not doing it like this

so they don't have raw values if you in here say unique part oh actually we can

see the value already here you can see it only contains trunk roof and tire so

it doesn't contain two roofs that's what I'm trying to get to so if you create a

simple enum in Swift without any raw values or any Associated values it's by

default hashable and Equitable all right that is the whole point now if you have

an enum with um with Associated values then you can

basically go ahead and change the hashing mechanism yourself so let's say

that we have an enum in here we call it house type and it has a big house and we

say its Associated value is a numbered house and we say case small house it is

a numbered house like this and then you can go ahead in

here and say this is hashable all right so as you do that Swift looks at the

properties that are inside this enum and it understands that oh this big house is

of course hashable because it's an inum case however it has an Associated value

then it looks at the associated value and says is this value hashable then it

goes to numbered house and it says yep it is hashable then it implements

hashable by default for you on this house type okay so then you can go ahead

and basically add these into some sort of a set so let's go ahead and we say we

create two big houses we say big house number one is a house type

big house like this and it has a numbered house inside it like this all

right and this number it has has a few properties it has a number and we say

number one and it is number of bedrooms is one as well so we have a big house

and that's number one in that street for instance and it has one bedroom for some

reason a big house with one bedroom only then we say a big house number two in

here okay let's get rid of this Bottom bar then we say it is also a big house

at number one and total number of bedrooms is one on that one as well then

we create a small house so we say small house one and like this small house one

it is a small house house and we say it is at number one as well and it's number

of bedrooms is one all right so now we have three houses with the same number

and two of them are actually the same house type as well so what's going to

happen if we go and put these inside a set so we say all houses is a set of

house type and is equal to a set with a big house

big house one big house two and small house one all right

so if you say all houses the count in here then let's see if the playground

can resolve this you can see there's only two objects in here the reason is

that big house one and Big House 2 are considered to have the same hash value

simply because that their numbered houses have the same hash value and

their cases have the same hash value however small house one is of type small

house not big house though it's numbered house has the same hash value as the

other numbered houses however the enum case itself also has a hash hash value

therefore in here you can see if I say all houses first and all houses actually

let's see if you can get the values inside the sets like this you can see we

have a let's see oh you can see the first one is a big house at number one

and if we say all houses last uh let's see if you can get the first does it

have a last item no it doesn't we can get the first unfortunately and let's

just say four value in all houses and then we type the value out in here let's

maybe even print the value like this so you will see then the first elements

inside all houses is a numbered house is a small house with that numbered house

and the second one is a big house meaning that the two big houses couldn't

actually occupy two separate spaces in the set simply because their hash values

are the same okay so I think that's actually enough right now about equality

and hashing we've talked quite a lot about them right now and I think you get

basically the idea so there's two different things you have to implement

or think about when it comes to equality hashing one is the hash of value which

determines whether two objects should consume the same space inside a set but

also you have to implement equality which determines whether two objects are

actually equal to each other okay and also you may sometimes just need objects

to be Equitable not hashable in in which case you can just implement it Equitable

protocol or conform to the Equitable protocol as long as all the properties

inside your structural class are equatable then you don't have to

implement a custom equality static function however you can always go ahead

and change the default implementation of both hashable and Equitable as well all

right now we're done with equality and hashing so let's start talking about

custom operators I'm going to close this playground in here so let's create a new

one a blank playground like this and then we call this one

custom operators all right and we create the playground

then we say import Foundation like that and then we can get rid of the Explorer

to the left hand side like this and we can run our playground

automatically now we've talked about operators to this point uh quite a bit

actually but we haven't talked about creating so many custom operators and

that's what we're going to do in this section of the code so let's say that

you have a first name and which is a string optional string and you say it is

actually equal to Foo though it is set as being the optional string and then

you create a last name in here and then you say bar now if you want to get the

full name and you say it should be equal to first name plus last name you'll see

that you get an error from Swift saying that this operator it is not defined

between you can see there is no operator that exists that matches this particular

signature left hand side optional string and right hand slide optional string if

these were not optional strings then you would have this operator you can see

that the error goes away let's see if we can get the definition actually for this

one A Plus operator I don't think we can unfortunately let's see a static Funk

Plus here we go there is that function

signature all right however the Swift Foundation framework hasn't defined the

same operator for optional strings so we can actually go ahead and do that

ourselves so let's say we have a funk plus and its left hand side is an

optional string and its right hand side is an optional string as well and it

returns an optional string okay then we go inside the function implementation

and we switch the left hand side and the right hand side if they are both none

meaning that they're both null then we return nil or actually not null but nil

Swift is one language that is chosen to use nil instead of null then we say okay

if then we get the left hand side so if we say case let we have some value on

the left hand side but no values to the right hand side

then we return the value to the left hand side so if you only have the first

name but not the last name then we return the first name as the full name

we do the opposite of this for last name as well so if the first name is is nil

but the right hand side has the value meaning that there is a is a family name

then we say return that value all right and we can join these two together like

this because they have the same pattern okay

and then we say if both of them have a value so we say sum left hand side and

some if I can spell some right hand side then we say return the left hand side

plus the right hand side okay as soon as you're done writing this function you

can see all of a sudden the errors go away and all of a sudden full name is

indeed equal to Foo bar all right so um we can also add a space in here

perhaps or add a space before bar so it becomes Foo plus bar right here okay

so that's how you can create a simple custom operator in Swift okay and I

think we've actually looked at something similar to this before maybe even

something more complicated all right now we haven't yet created our own unary

prefix operator this one was a binary in fix operator because it works with two

or binary and things two things therefore binary so this is a binary in

fix it is binary because it works with two operators and sorry with two

parameters and it's an infix operator because it says in between two values

okay however we haven't looked at unary

prefix operators so let's create a unary prefix operator let's have a look at an

example let's say that we have a lowercase naming here which is equal to

foobar and we want to turn it into uppercase Name by saying lowercase name

uppercase like this and this operator doesn't exist at the moment so you can

see it is we want to say unary unary prefix it is unary because it only works

with one argument to its left hand side and that's why it is called prefix

because it is it basically works with some actually no that is a that is a

suffix I would say that we need to move this here okay so this is a unary prefix

because it operate cases whatever it comes to its right hand side so prefix

because it is previous to the argument to its right hand side okay

so what we can do then is to go ahead and implement this operator but before

doing that since it is not an infix operator you actually have to Swift you

have to tell Swift that it is a prefix operator so you do that by saying prefix

operator it like this so you first tell Swift that this is a prefix operator

then you go ahead and Define a function for it so you say prefix func like this

oopsie lazy all right and then we work with a value

of type screen and we return a value of type string then we take the value and

we say uppercased oopsie Daisy uppercase like that now all of a sudden you can

see that this error will go away and our Foo BAR value will turn into Foo bar as

uppercase okay so that that is how you do a prefix operator

in Swift you have to first Define it as a prefix operator then you create the

function for it similar to this we can also create a unary postfix operators so

let's say that we have for instance um a name here which is fool bar and we

want to turn it into a star star star Fubar star star star like that okay so

whatever string we give our operator we wanted to prefix it with three stars and

a space and then a space and three stars after it okay so we say left with stars

is equal to lowercase name and then make sure you start it out so meanwhon a

unary post fix operator it is unary because it works only with one object to

its left hand side and therefore it's called post fix because it comes after

the element that it works with so let's define it we say postfix operator star

and then we say postfix func star it takes a value of type string and it

returns a string as well and what it does is that it just says star star

space value star star star okay and then you can see the value printed here will

then be star star Fubar space star star okay

so you can also Define your own custom binary infix operators on completely

unrelated types so it what we've looked at so far is that every time you work

with a binary infix operators both left hand side and right hand side were of

the same type however what happens if you have for instance a struct in here

let's say we have a struct of person and we say let name is a

string and then you have a struct family and then you say let members is an array

of persons okay then you go ahead and you say that you for instance have a mom

let's mom is person with the name of mom then we create a dad in here Dad we say

that and then we say Sun sun is Sun like that then we create

dollars so we say daughter one and his daughter one and daughter two all right

now what we want to do in here is to say and we want to create a family we say

family like this is Mom plus dad so Mom and Dad

create a family together however this operator at the moment is not defined

Swift doesn't understand what plus between two persons means so we can go

ahead and actually Define that so we say we have a function in here we say funk

Plus on the left hand side we take a person you see a person and right hand

side another person so we say a left-hand side person

and we say right hand side person I can understand that we said left hand side

and right hand side are probably going to be different types and we've so far

created binary infix operators with the same types for both parameters and we're

going to do something different now so you're probably asking yourself so why

aren't we doing something different but before we do that different thing that

we're going to do we have to first implement this function you'll see soon

okay so we first say if you create if you add two persons together we create a

family all right then in here we say we create a family with members equal to

this let's create these in separate lines like that

the members are at the left hand side and the right hand side okay now all of

a sudden you can see this error will go away and then you get a family in here

okay so that's one thing now what happens if

you then go ahead and say for instance family

with sun is equal to family plus some hmm does this work no it won't because

the left hand side of this operator is a family and the right hand side is a

person and what we've defined is plus between two persons not a family and a

person so what we're going to do is to go ahead and say func Plus on the LA on

the left hand side we're going to take in and we're going to take in a family

all right so we're gonna say on the left hand side we have family and the right

hand side we have a person and this returns also a new family then we go

ahead and we say we take the current families members family members then we

append to it the current uh the person to the right hand side

then we create a new family and return it with the given members like this all

right and then you can then see that this

error will also go away so you can say family dot members

dot count and then in here you say family with sun members.com which should

be one more than this family you can see it's three okay now what if you want to

say family with daughters so let's say family

with daughters and then you say okay take the family with the son and then

add a whole array of daughters to this so you say daughter one and daughter two

or S sorry not an array of daughters but an array of person you'll get an error

now because we still don't have an operator that can work on a an object on

the left hand side of type family and an object on the right hand side of type an

array of person but we can go ahead and Define that okay so we can say func Plus

on the left hand side we take a family and the right hand side we take an array

of persons and this guy returns a family all right so the way to do it is to say

VAR members again members equal to left hand side members then we

say members birth append contents of the right hand

side okay and then we return a family a new family with the new members

like this all right so now you can see this error will also go away and if you

say family with daughters dot members dot count then you should get the value

of five printed to the console in here okay so you can see how easy it is to

rationalize about how operators should work in Swift they're just simple

functions except for unaryfx and urinary postfix which you have to also create

these operator um tags kind of or declarations so this

is the implementation of the operator and this is the Declaration of the

operator okay so I think that is actually quite enough right now about

custom operators in the next section we're going to talk about some of the

new features uh inside Swift for a basically concurrency and

asynchronous Swift and that is going to be the last section for this course and

so without further Ado let's just get started with it I'm going to close this

tab in here and then I'm going to create a new playground and then let's say

playground and we call it async Swift all right and

we just say we want to import foundation and here is one of the exceptions where

we have to import three things we say import also playground support and then

we import import concurrency concurrency like this

and we're doing this playground support here simply because asynchronous code

requires that our playground is active all the time and it doesn't just start

from the beginning and ends and when the when it encounters the end of the file

we just need the playground to stay alive simply because concurrent code and

and asynchronous code requires that kind of behavior because if you make an API

call that takes three seconds to finish maybe before that API call is done your

playground has already reached its and it just terminates and you don't want

that so let's go and say playground support sir playground page at dot

currents page and then we say needs indefinite execution equal to true so if

you're running your code on a Macintosh in xcode then you have to do this but if

you're on Windows or Linux and you're in Visual Studio code I'm just running your

code using simple Swift then you shouldn't really do this you should

perhaps just create a simple project that can have a main Loop and then you

can then execute your code inside that main Loop That Never Ends okay and

however if you're in a playground then you will need to do this on Mac OS all

right now let's say that we want to create a

simple asynchronous function in Swift if you're already familiar with dart for

instance for flutter or python or rust you probably have already used Tokyo

perhaps in rust or in Dart you also have Futures and stream stream controllers

you're probably already familiar with asynchronous code but if you're not I'll

just quickly brief you on what it means it means if you have an asynchronous

function it will not immediately return its result it can take any number of

seconds or milliseconds to complete its work and return some value and perhaps

it won't even return a valuesome asynchronous functions don't return a

value okay so let's go ahead and create a simple dummy function in here which we

call calculate full name so we say funk calculate full name all right then we

say we have a first name first name is string and then we have a last name

which is a string then we say it is an async function which returns a string

okay so by creating this asynchronous function in here you'll have the ability

to basically delay the return of your results so you can in here just say

return hello you could definitely do that but that's not the point of async

functions this is asynchronous function not an asynchronous function a

synchronous function returns this value immediately and asynchronous function

might take some time before it returns its value so let's go ahead and say we

try to await on a task by sleeping for the duration of one second so this is

how you would create a delay a fake delay in your function all right and

we're using the try with question mark syntax in here because we're not

throwing okay if this function throws then we didn't have to do that

however we're saying that our function is an async function that doesn't throw

let's also Mark our playground as automatically running

so we say try and we say await and let's say cannot convert return expression

okay and here then we can say return after waiting one second return the

first name with the space and the last name as the result of this function all

right that error is now going to go away now inside your playground if you want

to call this asynchronous asynchronous function you have to create a task and

then you can say let result 1 is equal to a weight on the result of calculating

the full name the full name comes from the values of Foo and Bar in here okay

and you can see the result is actually Foo bar all right it waited before it

calculated the value for us then we can also go ahead I mean you can see in here

we have let result equal to a weight but there is another syntax word in Swift

which is called async let and you can say async let result 2 is calculate and

so you can see how async is before the let and then we say take Foo bar again

as the values and in here if you want to if you want to wait for the result of

this you have to await on it so you say a way to resolve to now asynclet is a

little bit more special because it creates a child task as part of this

task you can read about it in Swift Evolution on GitHub and so I won't go

too much into it but it is kind of similar to this guy uh but it has a

little bit difference in like how you await on it because some developers

think maybe that oh this by default awaits on this but it doesn't okay you

have to wait on the result yourself manually okay so that's how you can

create a simple task in asynchronous task and then do some async and a weight

code inside it in Swift now we can go ahead and put together

maybe an example that talks about async and async let's and tasks all together

just to make it stick a little bit more okay so let's say we create a cloth enum

in here and we say we have case socks we have shirts and trousers all right then

let's create some asynchronous functions in here so we say the first function

that we have is called buy socks all right and it is an async function that

throws and we say it returns a clove and what it does is it says try a weight

on a task by sleeping for a duration of one second and the reason this function

throws is that we're not doing try like this if we did try with a question mark

we didn't have to throw okay but we're doing just normal try therefore the

function has to throw or it has to be inside I do but what we're indicating to

the outside world by writing this function and seeing that this function

is an asynchronous function that can internally actually throw an error so be

careful while consuming its value all right then we return a close of type

socks so after one second we produce an item of clothing

after doing this one we can go ahead and create another function which is called

by shirt like this and it produces an item of clothing and ins in here we just

say shirt all right and we can create another one that produces a item of

trousers so we say trousers and it says dot trousers all right so they're very

similar to each other they just return a different result of them now you want to

create a structure in here that is an ensemble an ensemble is a you can say it

is a collection of clothing clothes items and you can say struct Ensemble

all right and then we say this guy has clothes in it and we say it is an array

of clothes and it has a total price price of type double all right doesn't

really matter what the currency for the prices we also want this Ensemble to be

printable to the console in a very nice format so we can form it to custom debug

string convertible protocol and therefore we have to implement a new

variable here called debug description like this we make it a computed property

and then we say clothes equal to clothes and we say price is equal to total price

so the value that you're producing here will then be printed to the debug

console whenever you try to debug an instance of this Ensemble structure okay

now we create a function in here called by whole ensemble

like this and we say it it's an async function that throws and it produces an

ensemble in here okay then we should go ahead and buy all our uh parts so we say

async LED socks is buy socks async let shirt is by shirt and async lets

trousers is by trousers all right so since all these are async let's then we

need to await on them and also we should also sorry not also also twice now

became four times so what we want to do is to go and

create an ensemble so we say let's Ensemble on uh symbol is an instance of

Ensemble and it says okay give me the clothes and you probably think okay I'm

just gonna give it socks shirt and trousers but you can't do that because

these are async let's items you have to await on them so just type a weight and

then we go ahead in here we say socks a shirt trousers but since these guys are

also throwing functions you have to try them okay so you say try try try

and then for the total price we're gonna say the total price is 200 okay

there we go and then we can return The Ensemble like this now all these errors

are hopefully gonna go away so there we go

now you can to test this you create a task in your playground and then you can

say a flat Ensemble is equal to try a weight on buy

hola Ensemble then you can say Ensemble is this otherwise something went wrong

like that all right and then you can see our Ensemble debug description will be

printed to the screen says clothes are this let's see if you can get the entire

clothes maybe we could print it even so print

it's a little bit easier perhaps to read it here

there we go so it says is a shirt it's a socks trousers and also the price is 200

dollars let's say okay now async lab can only be used within asynchronous

closures and asynchronous functions or wherever there is a task being run so

you cannot use asynchronous async let within uh anything that is not one of

the ones that I just described so it should be an asynchronous closure an

asynchronous function or wherever there is a task that you have such as in here

okay so let's let's have a look at a few examples we go in here and we just say

funk get full name and we ask for a delay a fake delay and we say it's of

type duration and we say we have a calculator for

what we calculate like how we calculate the full name and it is an async

function that returns a string in here and then we say it is async

function add it in itself returns a string so our job is just to try to

await on this uh task sleep for this delay and then we return and we want to

return the result of this function but it is an async function so we have to

await on it so we say wait on the calculator like this all right and then

you can see all these errors are then going to go away and then we have our

print statement in here let's just remove it so that we don't get this

print in the console all right now that we have that we can go ahead

and actually say we have a funk and we call it full name and we say it's an

async function which is an error function and we just for now just we say

Foo bar all right so it is an async function but right now it just returns

asynchronous result back to us full name like this then we can create a task and

we can say await on get full name and we say uh let's break these down and then

we say the delay is in delay in seconds one and its calculator is indeed uh

let's actually see for the calculator let's create a a trail enclosure in here

then we say async let name is full name and then we can say return awaits name

all right so let's see if we get the results printed to the screen now you

can see Fubar then being printed to the screen so we could use async let simply

because we're in a an async trailing closure okay and also we've been able to

use asynclet in other contexts such as here which we're in an async function

all right so I mean there's a lot more actually to

talk about when it comes to asynchronous programming with swift but this just

gives you an idea of the basics of asynchronous programs very similar to

JavaScript and typescript and you could also say it's very similar to actually

Dart for instance for those of you who do flutter development it's a little bit

more complicated because well it is Swift it has a long history of its own

code base and there are a lot of people contributing to Swift as a programmable

language not even just people just inside Apple so it is somehow a mishmash

of everything the community thought was a good idea to add to Swift I personally

don't like for instance async let I think it makes things more complicated

almost every other program language that has asynchronous programming such as

JavaScript typescript and dart don't need async lab they just do async and a

weight and everything works as expected I think async lab adds a new layer of

complexity to your code which is unnecessary

some people may argue that it is actually nice but I personally don't

like it so much but that's just my opinion and I think it although I don't

like it so much I learn it and I think it is important that we all learn how to

use these syntaxes that are available in modern Swift so with that said I think

we can then conclude this particular video of the full stack with swift

course and we've talked a lot about you can see we have so many playgrounds in

here I can't even count but we talk about variables operators classes

expenses generics pretty much everything that you can think of in Swift so now

what we're gonna do in the course is to go ahead and start talking about client

development and also back-end development with Swift I really hope

that you enjoyed this video if you found it helpful please press the thanks

button at the bottom of the screen or you can just alternatively join my

YouTube channel so see you in the next video

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