{"id":639,"date":"2016-11-01T13:30:54","date_gmt":"2016-11-01T13:30:54","guid":{"rendered":"http:\/\/jonescarvalho.com\/Blog\/?p=639"},"modified":"2020-05-13T20:51:49","modified_gmt":"2020-05-13T23:51:49","slug":"swift-funcoes","status":"publish","type":"post","link":"https:\/\/jonescarvalho.com\/Blog\/?p=639","title":{"rendered":"Swift &#8211; Fun\u00e7\u00f5es"},"content":{"rendered":"<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">\n\/\/ Swift - Fun\u00e7\u00f5es\n\n\/*\nDefini\u00e7\u00e3o de Fun\u00e7\u00e3o\nComo em qualquer outra linguagem, fun\u00e7\u00f5es s\u00e3o blocos de c\u00f3digo (nomeados), com uma finalidade espec\u00edfica\nUma fun\u00e7\u00e3o tem um nome, pode ter par\u00e2metros (argumentos) e tamb\u00e9m pode ter um valor de retorno (Em Swift, pode ter mais de um valor de retorno)\n\nBOAS PR\u00c1TICAS:\n1) Uma fun\u00e7\u00e3o deve ter uma \u00fanica finalidade\n2) O nome da fun\u00e7\u00e3o deve dar uma ideia da sua finalidade\n3) Evite codificar fun\u00e7\u00f5es com \"milhares de linhas de c\u00f3digo\"\n4) Procure dar nomes em ingl\u00eas ou em portugu\u00eas, mas siga um padr\u00e3o\n\nSintaxe na Swift:\nfunc &lt;nome fun\u00e7\u00e3o&gt; (&lt;nome par\u00e2metro1&gt;: &lt;tipo par\u00e2metro&gt;, &lt;nome par\u00e2metro2&gt;: &lt;tipo par\u00e2metro&gt;, ...) -&gt; &lt;tipo do retorno&gt; {\n\/\/ Corpo da fun\u00e7\u00e3o\n...\n}\n*\/\n\n\/\/ 1 - Fun\u00e7\u00e3o simples - sem par\u00e2metros e sem valor de retorno\nfunc sayHello1() {\nprint(\"Ol\u00e1 Alunos! Sejam bem-vindos!\")\n}\n\n\/\/ Chama a fun\u00e7\u00e3o simples\nsayHello1()\n\n\/\/ 2 - Fun\u00e7\u00e3o com par\u00e2metro, mas ainda sem valor de retorno\nfunc sayHello2(nomePessoa: String) {\nprint(\"Ol\u00e1, \\(nomePessoa)\")\n}\n\n\/\/ Chama a fun\u00e7\u00e3o passando o par\u00e2metro\nsayHello2(nomePessoa: \"Jones\")\nsayHello2(nomePessoa: \"Edivaldo\")\n\n\/\/ 3 - Sintaxe completa - com par\u00e2metros e valor de retorno\nfunc sayHello3(nomePessoa: String) -&gt; String {\nlet cumprimento = \"Ol\u00e1, \" + nomePessoa + \"!\"\nreturn cumprimento\n}\n\n\/\/ Chama a fun\u00e7\u00e3o completa\nlet resposta = sayHello3(nomePessoa: \"Jones\")\nprint(\"\\(resposta). Voc\u00ea \u00e9 o nosso novo aluno\")\n\n\/\/ 4 - Fun\u00e7\u00f5es com m\u00faltiplos par\u00e2metros\nfunc sayHello4(personName: String, alreadyGreeted: Bool) -&gt; String {\n\nif alreadyGreeted {\nreturn \"Ol\u00e1, \" + personName + \", novamente\"\n} else {\nreturn \"Ol\u00e1 \" + personName\n}\n}\n\n\/\/ Testando a fun\u00e7\u00e3o com m\u00faltiplos par\u00e2metros\nvar retorno = sayHello4(personName: \"Jos\u00e9\", alreadyGreeted: false)\nretorno = sayHello4(personName: \"Jos\u00e9\", alreadyGreeted: true)\n\n\/\/ NOVIDADE SWIFT\n\/\/ Fun\u00e7\u00e3o com m\u00faltiplos valores de retorno\nfunc minMax(array: [Int]) -&gt; (min: Int, max: Int) {\n\n\/\/ A finalidade aqui \u00e9 pesquisar, respectivamente, os valores n\u00ednimo e m\u00e1ximo de um array de inteiros\nvar currentMin = array[0]\nvar currentMax = array[0]\n\nfor value in array[1..&lt;array.count] {\nif value &lt; currentMin {\ncurrentMin = value\n} else if value &gt; currentMax {\ncurrentMax = value\n}\n}\n\n\/\/ Retorna os dois par\u00e2metros num \u00fanico retorno\nreturn (currentMin, currentMax)\n}\n\n\/\/ Como chamar essa fun\u00e7\u00e3o?\nlet valores = minMax(array: [8, -6, 2, 109, 3, 71])\nprint(\"O menor valor \u00e9 \\(valores.min) e o maior valor \u00e9 \\(valores.max)\")\n\n\/\/ Apenas para tipificar o tipo de retorno\nprint(type(of: valores))\n\n\/\/ Labels de Argumento e Nomes de Par\u00e2metros\n\/\/ Cada par\u00e2metro pode ter um label de argumento seguido de um nome de par\u00e2metro\n\/\/ O label \u00e9 utilizado na chamada da fun\u00e7\u00e3o\n\/\/ O intuito \u00e9 documentar melhor as chamadas\n\n\/\/ Declara\u00e7\u00e3o\nfunc funcao(LabelArgumento NomeParametro: Int) {\n\n}\n\n\/\/ Exemplo SEM e COM par\u00e2metros nomeados\n\n\/\/ Para receber o retorno das fun\u00e7\u00f5es\nvar retornoJoin: String\n\n\/\/ 1 - Forma normal (sem par\u00e2metro nomeado)\nfunc join(s1: String, s2: String, joiner: String) -&gt; String {\nreturn s1 + joiner + s2\n}\n\n\/\/ Chamando a fun\u00e7\u00e3o normal\nretornoJoin = join(s1: \"Hello\", s2: \"World\", joiner: \", \")\n\n\/\/ 2 - Com labels de argumentos e nomes dos par\u00e2metros\nfunc joinPE(string s1: String, toString s2: String, withJoiner joiner: String) -&gt; String {\nreturn s1 + joiner + s2\n}\n\nretornoJoin = joinPE(string: \"Hello\", toString: \"World\", withJoiner: \", \")\n\n\/\/ Omitindo labels de argumentos\n\/\/ Caso vco\u00ea n\u00e3o queira especificar um label de argumento, ele pode ser omitido atrav\u00e9s da escrita de um caracter sublinhado (_)\n\n\/\/ Declara\u00e7\u00e3o\nfunc someFunction(_ primeiroParametro: Int, segundoParametro: Int) {\nprint(\"Valor do primeiro par\u00e2metro: \\(primeiroParametro)\")\nprint(\"Valor do segundo par\u00e2metro: \\(segundoParametro)\")\n}\n\n\/\/ Chamando a fun\u00e7\u00e3o, com label omitido\nsomeFunction(1, segundoParametro: 2)\n\n\/\/ Mais um recurso interessante: par\u00e2metros com valor default (pr\u00e9-definidos)\n\n\/\/ Fun\u00e7\u00e3o com m\u00faltiplos par\u00e2metros e par\u00e2metro default\nfunc login(name: String, withLastName: String? = \"Savi\", isEnable: Bool) -&gt; String {\n\n\/\/ Uma pitadinha de guard\n\/\/ A ideia \u00e9 executar a fun\u00e7\u00e3o apenas se o par\u00e2metro isEnable for true\nguard isEnable else {\nreturn \"A fun\u00e7\u00e3o s\u00f3 ser\u00e1 executada se o par\u00e2metro isEnable for true\"\n}\n\n\/\/ Com c\u00f3digo seguro\n\/\/ Visando garantir que o par\u00e2metro contenha um valor v\u00e1lido\n\/\/ Podemos usar o valor passado na chamada ou o valor default\nif let lastName = withLastName {\nreturn \"Bem-vindo de volta \\(name) \\(lastName)\"\n}\n\n\/\/ Se o par\u00e2metro n\u00e3o for especificado, utilizaremos o valor default\nreturn \"Bem-vindo \\(name)\"\n\n}\n\n\/\/ As formas de chamar essa fun\u00e7\u00e3o\n\/\/ 1 - Omitindo o par\u00e2metro default\nvar info = login(name: \"Carlos\", isEnable: true)\n\n\/\/ 2 - Declare um valor default (v\u00e1lido)\ninfo = login(name: \"Pedro\", withLastName: \"Farias\", isEnable: true)\n\n\/\/ 3 - Declarando o valor default (inv\u00e1lido)\ninfo = login(name: \"Jo\u00e3o\", withLastName: nil, isEnable: true)\n\n\/\/ 4 - Parando no guardi\u00e3o da fun\u00e7\u00e3o - guard\ninfo = login(name: \"Carlos\", isEnable: false)\ninfo = login(name: \"Carlos\", withLastName: \"Carvalho\", isEnable: false)\n\n\/\/ Fun\u00e7\u00e3o com par\u00e2metros variadic\n\/\/ Onde o n\u00famero de par\u00e2metros \u00e9 vari\u00e1vel\n\/\/ Restri\u00e7\u00f5es:\n\/\/ - Se a fun\u00e7\u00e3o tiver mais par\u00e2metros, o variadic deve ser o \u00faltimo\n\/\/ - S\u00f3 pode haver 1 variadic por fun\u00e7\u00e3o\nfunc mediaAritmetica(numeros: Double...) -&gt; Double {\nvar total: Double = 0\nfor numero in numeros {\ntotal += numero\n}\nreturn total \/ Double(numeros.count)\n}\n\n\/\/ Usando a variadic\n\n\/\/ Para receber o retorno do c\u00e1lculo\nvar media: Double?\n\n\/\/ Exemplos de chamada\nmedia = mediaAritmetica(numeros: 1, 2, 3, 4, 5)\nmedia = mediaAritmetica(numeros: 10, 20)\nlet num = 10.0\nmedia = mediaAritmetica(numeros: num, 20, 30)\n\n\/\/ Fun\u00e7\u00e3o com par\u00e2metros in-out\n\/\/ Na fun\u00e7\u00e3o tradicional, ocorre uma c\u00f3pia dos valores passados como par\u00e2metros. Os valores originais n\u00e3o s\u00e3o alterados pelo processamento da fun\u00e7\u00e3o\n\/\/ E se eu quiser que a fun\u00e7\u00e3o atualize as veri\u00e1veis que estou passando como par\u00e2metros?\n\/\/ Utilizando par\u00e2metros in-out, \u00e9 passado \u00e0 fun\u00e7\u00e3o os enderede\u00e7os de mem\u00f3ria das vari\u00e1veis, e n\u00e3o uma c\u00f3pia. Desta forma, a fun\u00e7\u00e3o consegue altere os valores originais.\n\n\/\/ 1 - A forma tradicional\n\/\/ A finalidade aqui \u00e9 trocar (inverter) os valores de 2 inteiros\nfunc troca2Inteiros(a: Int, b: Int) {\nlet temporaryA = a\n\/\/ N\u00e3o consguimos ter acesso \u00e0s vari\u00e1veis originais, pois elas foram passadas como c\u00f3pia e s\u00e3o do tipo let\n\/\/ As instru\u00e7\u00d5es baixo geram um erro de compila\u00e7\u00e3o\n\/\/ a = b\n\/\/ b = temporaryA\n}\n\n\/\/ O par\u00e2metro in-out resolve essa limita\u00e7\u00e3o\nfunc trocaDoisInteiros(a: inout Int, b: inout Int) {\nlet temporaryA = a\na = b\nb = temporaryA\n}\n\n\/\/ Chamada da fun\u00e7\u00e3o\nvar umInt = 3\nvar outroInt = 107\n\n\/\/ Ao chamar uma fun\u00e7\u00e3o com par\u00e2metros inout, utilizaremo ponteiros, ou seja, passaremos n\u00e3o a c\u00f3pia mas o endere\u00e7o de mem\u00f3ria das vari\u00e1veis\ntrocaDoisInteiros(a: &amp;umInt, b: &amp;outroInt)\nprint(umInt)\nprint(outroInt)\n\/\/ Os valores originais foram trocados\n\/\/ Aqui uma das rar\u00edssimas situa\u00e7\u00f5es na linguagem Swift, onde utilizamos ponteiros\n\n\/\/ Uma fun\u00e7\u00e3o pode ser um tipo de dados, na Swift\nfunc soma2Ints(a: Int, b: Int) -&gt; Int {\nreturn a + b\n}\n\nfunc multiplica2Ints(a: Int, b: Int) -&gt; Int {\nreturn a * b\n}\n\n\/\/ Para receber o resultado do c\u00e1lculo\nvar calculo: Int?\n\n\/\/ Consguimos ent\u00e3o, definir uma vari\u00e1vel do tiupo fun\u00e7\u00e3o?\nvar mathFunction: (Int, Int) -&gt; Int = soma2Ints\n\n\/\/ E como usar isso?\ncalculo = mathFunction(2, 3)\n\n\/\/ Posso variar as condi\u00e7\u00f5es\nmathFunction = multiplica2Ints\ncalculo = mathFunction(2, 3)\n\n\/\/ A infer\u00eancia tamb\u00e9m funciona\nlet anotherMathFunction = soma2Ints\n\n\/\/ Fun\u00e7\u00f5es aninhadas\nfunc retornaQuinze() -&gt; Int {\nvar y = 10\n\/\/ Fun\u00e7\u00e3o aninhada\nfunc add() {\n\/\/ A fun\u00e7\u00e3o interna (aninhada) tem acesso \u00e0s propriedades da fun\u00e7\u00e3o externa\ny += 5\n}\n\/\/ A fun\u00e7\u00e3o externa consegue chamar a fun\u00e7\u00e3o interna (aninhada)\nadd()\nreturn y\n}\n\n\/\/ Testar a fun\u00e7\u00e3o ainhada\nlet retornoFunc: Int?\n\n\/\/ Para o mundo exterior, apenas a fun\u00e7\u00e3o extermna \u00e9 vis\u00edvel\nretornoFunc = retornaQuinze()\n\/\/ No entanto, a fun\u00e7\u00e3o interna n\u00e3o \u00e9 acess\u00edvel\n\/\/ A linha est\u00e1 comnentada pois gera um erro de compila\u00e7\u00e3o\n\/\/retornoFunc = add()\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>\/\/ Swift &#8211; Fun\u00e7\u00f5es \/* Defini\u00e7\u00e3o de Fun\u00e7\u00e3o Como em qualquer outra linguagem, [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2],"tags":[40,43,45,44,39],"class_list":["post-639","post","type-post","status-publish","format-standard","hentry","category-dicas","tag-ios","tag-minmax","tag-ordenacao","tag-order","tag-swift"],"_links":{"self":[{"href":"https:\/\/jonescarvalho.com\/Blog\/index.php?rest_route=\/wp\/v2\/posts\/639"}],"collection":[{"href":"https:\/\/jonescarvalho.com\/Blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/jonescarvalho.com\/Blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/jonescarvalho.com\/Blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/jonescarvalho.com\/Blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=639"}],"version-history":[{"count":3,"href":"https:\/\/jonescarvalho.com\/Blog\/index.php?rest_route=\/wp\/v2\/posts\/639\/revisions"}],"predecessor-version":[{"id":850,"href":"https:\/\/jonescarvalho.com\/Blog\/index.php?rest_route=\/wp\/v2\/posts\/639\/revisions\/850"}],"wp:attachment":[{"href":"https:\/\/jonescarvalho.com\/Blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=639"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/jonescarvalho.com\/Blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=639"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/jonescarvalho.com\/Blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=639"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}