클로저 기초 1

swift 2023. 7. 10. 23:14

반응형

클로저 공부 중 정리와 암기를 위한 타이핑용 포스팅이며 원본은 야곰이란 분의 포스팅을 보는걸 추천함
(https://www.boostcourse.org/mo122/lecture/11296)
컴파일러 없이 웹상에서 간단하게 playground 환경으로 테스트 하기 위한 경우 아래 링크에서 swift 문법 테스트가 가능함
https://www.onlinegdb.com/online_swift_compiler

클로저란?
실행가능한 코드 블럭
일급객체로 변수, 상수, 전달인자 등에 저장은 물론 전달이 가능
클로저는 이름이 있는 클로저와 이름이 없는 클로저로 존재
함수도 클로저의 일종으로 이름이 클로저임
함수와 다르게 이름 정의는 필요하지 않고, 매개변수 전달과 반환 값이 존재 할 수 있다란 점은 동일함

클로저 기본 문법
{(매개변수 목록) -> 반환타입 in
    실행코드
}

클로저 기본 사용 방법
var든 let이든 상관없이 선언 후 선언된 변수나 상수에 클로저를 할당하면 됨
var printName:(String, String)->String = {(firstName:String, lastName:String) in
    return firstName + lastName
}
1. var printName printName이란 변수를 선언
2. (String, String)->String String형태로 인자 2개를 받고 이를 String형태로 리턴해준다란 의미
3. firstName:String, lastName:String 인자 이름은 첫번째가 firstName, 두번째가 lastName
4. 실행코드의 구분은 in 전후로 나뉘고 실행코드는 return firstName + lastName 이므로
    넘겨받은 첫번째, 마지막 이름을 연결해서 리턴해줌

함수의 전달인자인 클로저
클로저는 주로 함수의 전달인자로 많이 사용된다 함.
함수 내부에서 코드블럭을 실행 할 수도 있다 함.
그런데 뭔말인지 모르겠음. 쉽게 생각해보면 작고 귀엽고 간단한 클로저를 하나 먼저 만들고
이 귀염뽀찍 클로저를 다른 함수에 전달해서 함수에서 호출하고 지지고 볶는 그런 느낌인가 봄
먼저 4칙연산 중 덧셈 클로저를 만들어보겠음
let add: (int, int) -> int
뭔가 이상하지 않음?
int의 i가 대문자여야 함 다시 작성하겠음(이러면서 문법과 친해지는거임)
let add: (Int, Int) -> Int
add = { (a: Int, b: Int) in
    return a + b
}

위처럼 작성해도 되고 아래처럼 작성해도 됨

let add2: (Int, Int) -> Int = {(a: Int, b: Int) in
    return a + b
}

아직까진 swift가 지멋대로 축약질에 변동성이 너무 강해 짜증이 남.
요즘 언어들은 싸가지들이 없음.
근본이 없음. 지들만 잘난냥 떠들어재끼는 MZ들처럼

함수를 만들어줌
a,b를 인자로 Int형을 받고 아까 말했듯이 클로저를 함수에 전달할 수 있으니 이부분을 method라는 이름으로 구현해줌
func calc(a:Int, b:Int, method:(Int, Int)->Int)->Int {
    return method(a, b)
}
조금 분해해서 살펴보면
함수니까 func라고 쓰고 함수이름 아무거나정해서 calc라고 적었음
함수니까 괄호열어주고 (
전달받는 인자는 2개 그다음이 클로저인데 앞서 add클로저를 보면 let add: (Int, Int) -> Int 임
여기에서 let add: (Int, Int) -> Int 앞에 let add어쩌구는 제끼고 그 뒤엣것만 가지고 온거임
함수니까 괄호닫아주고 )
그리고 리턴형이 Int니까 -> Int 써준게 전부
그 다음은 함수 실행부이니 전달받은 클로저를 전달한 인자 a,b로 그냥 실행 method(a, b)

함수까지 만들었으니 이제 실행하면 됨.
먼저 Int형 변수 하나 선언해주고
var nCalcResult:Int

이 변수에 아까 만든 calc라는 함수를 불러와 넣어줌
이때 method는 클로저인 add 클로저를 호출하면 됨
nCalcResult = calc(a:1, b:1, method:add)

그럼 결과는 
print(nCalcResult) 
2

당연하겠지만 아까 조금 다르게 만든 클로저인 add2를 호출해도 결과는 동일하게 2로 잘 나옴
nCalcResult = calc(a:1, b:1, method:add2)
print(nCalcResult)

덧셈을 해봤으니 이제 뺄셈 나눗셈 곱셈 등을 동일한 방식으로 구현해보면 됨
let substract:(Int, Int) -> Int = {(a:Int, b:Int) in 
    return a - b
}
이렇게 하면 되고
처음에서처럼 아래처럼 하면 됨
let substract:(Int, Int) -> Int
substract = {(a:Int, b:Int) in
    return a - b
}

여전히 익숙하지 않은자를 위해 클로저 문법 안 까먹고 익히는 비법 공유함.
똑같이 반복해서 구간 구간을 점차 완성시키는 방식으로 스스로 타이핑 해보길 강권함.
let 
let substract
let substract:() -> 
let substract:(Int, Int) -> Int
여기까지가 1절 완성임

substract = {
}
substract = {()
}
substract = {(a:Int, b:Int)
}
substract = {(a:Int, b:Int) in
    return a - b
}

최종
let substract:(Int, Int)->Int
substract = {(a:Int, b:Int) in
    return a - b
}

이거 따라했으면 절대 안 까먹음
응용 복습하는 생각으로 나눗셈 만들기 스타또
let divide:(Int, Int) -> Int
divide = {(a:Int, b:Int) in
    return a / b
}

정말 마지막으로 곱셈
let multiple:(Int, Int) -> Int
multiple = {(a:Int, b:Int) in
    return a * b
}

이쯤되면 아까 함수 만드는거 까먹었을 거
func calc(a:Int, b:Int, method:(Int, Int) -> Int) -> Int {
    return method(a, b)
}

var nCalcResult: Int
nCalcResult = calc(a:10, b:2, method:divide)
print(nCalcResult)

곁다리로
클로저 표현을 let add:(Int, Int) -> Int = {(Int:a, Int:b) in 대신에 Int를 빼고 이렇게도 가능함
let add:(Int, Int) -> Int = {(a, b) in
    return a + b
}

반응형

'swift' 카테고리의 다른 글

클로저 기초 2  (0) 2023.07.11
swift int 변수를 string형으로 변환 그리고 비교  (0) 2018.11.21
Posted by Hippalus
,

반응형

본격적인 여름 시즌
서울시 강북구 번동에 위치한 북서울꿈의숲에 물놀이 장소가 두 곳 존재한다.
서문쪽에 위치한 바닥 분수대 시설과 북서울 꿈의숲 중간에 위치한 상상톡톡미술관 앞에 개울처럼 흐르는 인공 물놀이 시설
서문쪽 분수대와 중앙쪽 상상톡톡미술관 앞 개울은 걸어서 5분 정도 거리이다.
참고로 북서울 꿈의숲은 언덕위에 위치한 서문이 정문이고 평지인 동문은 후문이다.
동문은 현재 경전철 공사가 진행중인 곳이고 입구가 매우 넓다.(평지인 장위동 쪽)
정문인 서문은 높은 타워(이병헌 주연 아이리스 드라마 촬영지로 소개되었던 경사 엘리베이터)가 있는 곳 이다.

서문쪽 분수대

장점
1. 분수시설이 여러곳이다.
2. 당근 바닥 분수대는 아이들이 좋아한다.
3. 편의점이 바로 옆에 있다.
4. 서문 주차장에서 가깝다.

단점
1. 12시부터 분수가 솟아오른다.
    부지런한 인간들이 10시 부터 건물 그늘 명당에 자리잡고 있는다. (한 30%이상 차 있던데 2시간동안 뭐하려고 저러는지들)
2. 바닥 분수만 존재한다. 위에서 무언가 쏟아지는게 없다.
3. 인근 쓰레기 시설이 있어 3곳 분수시설 중 한곳에선 냄새가 날 수 있다.
    쓰레기 냄새는 딱 그 선까지만 날 뿐 인근 아파트 단지인 동문 아파트에선 나지 않는다. 신기하다.
4. 서문 주차장은 동문 주차장에 비해 협소하다.



상상톡톡미술관 개울

장점
1. 개울이라 어린 아이들이 놀기 좋다. 분수대쪽은 아이들이 뛰어다니고 정신 없을 수 있다.
2. 상류지에 수원지처럼 조형물이 있어 올라가서 놀기도 좋다.
3. 하류지에 캐리비안베이처럼 폭포가 쏟아진다.
4. 상상톡톡미술관 바깥에 화장실이 있다. (분수대쪽은 건물로 들어가서 안쪽으로 더 들어가야 있는데 거기서 거기긴하다.)
5. 일찍와도 이용이 가능하다.(다만 폭포는 12시 부터인가 쏟아진다.)

단점
1. 분수처럼 활동성을 기대하기 힘들다.
2. 돗자리 펼 곳이 분수대만큼 많지 않다.(한 60% 수준)


북서울 꿈의 숲 상상톡톡미술관 개울 명당 자리 잡는 꿀팁
먼저 일찍일어나는 새가 벌레를 잡는 법. 일찍오면 된다.
10시에 도착해서 자리를 잡아야 하는데 무조건 일찍 와서 좋아보이는 자리 덥썩 잡으면 바보다.
아래 사진처럼 가장 좋은 자리는 개울 바로 앞이지만 12시가 지나면 슬슬 해가 들이치기 시작한다.

반면 그 바로 뒤 자리는 해가 뜨든 말든 노상관
따라서 괜히 애들 노는거 잘 보겠다고 개울 앞 자리가 명당인줄 알고 착각하고 돗자리 펴다 봉변당하지 말자.
아래 사진처럼 이 중앙 자리가 개명당이다.
이 자리가 없으면 이 자리 뒷편에도 펼 수 있다.
상상미술관 중앙에 흰색으로 보행자들이 드나들 수 있는 공간만큼만 침범하지 않으면 된다.

정리하자면 총 3구역에 돗자리를 펼 수 있는데 맨 앞열은 12시 이전에 집으로 돌아갈 사람들에게 양보해주고
그 뒷자리가 1순위 뒷뒷 라인자리가 2순위다.
2순위도 1순위와 거의 동급이라 보면 된다.
개울 앞 자리만 피하면 된다.(뭣 모르면 사람들은 앞자리부터 럭키 외치며 잡아주니 땡큐다)
전체적으로 15팀 ~ 20팀 정도 자리를 펼 수 있다.

개울 앞에는 안전요원과 탈의실이 존재한다.
이는 서문쪽에도 마찬가지로 존재한다.

주차팁은 서문의 경우 공원내 레스토랑이나 중식당에서 식사를 하면 2시간인가 1시간인가 주차권을 발급해주니 이를 활용함이 좋다.
중식당은 그렇게 비싸진 않고 맛도 그럭저럭 공원 시설내에 있는것이라 보기엔 훌륭한 맛이 보장된다.
중식당명은 하오런이고 올라가는 길은 경사 엘리베이터가 있지만 5~6명 타면 정원초과되니 스트레스 받지 말고 그냥 에스컬레이터와 도보로 올라가는걸 추천한다.

끝으로 상상톡톡 미술관 아래쪽으론 요런 기와집과 대나무 숲 그리고 분수대, 호수, 사슴쉑히 등등을 볼 수 있으니 물놀이만 즐기지 말고 카페와 다른 시설들도 이용해보길 권장한다.

정말 끝으로 동문쪽엔 춘천골 닭갈비란 조그마한 식당이 있는데 이 집 닭갈비 맛있다.(주차는 못한다 보면 된다.)
일단 기본 안주로 오뎅 나오고 특이한건 광어회로 만든 스시까지 판다. -_-
스시는 비추한다.
YES KIDS 존인 맥도날드도 있다.
또 인근 맛집으로는 뭐 신축 아파트 단지 앞에 빽다방도 있고 길 건너에 역전앞 할맥도 있다.

정말 정말 끝으로 인근에 불법 주차 하는 인간들 있던데 여기 구청에서 종종 단속 한다.
자전거전용도로에 뙇!~
그냥 일찍와서 맘 편하게 공영주차장에 대는게 여러모로 개이득이다.
즐겁게 놀고 과태료 맞으면 마음 아프잖아?

반응형
Posted by Hippalus
,

반응형

보통 서버에 오만 잡다한 파일들이 존재하기 마련이다.
xlsx, csv, gif, jpeg, png 등등
간단한 구조라 psd 폴더에만 사용자 업로드 파일들이 존재한다면야 상관없겠지만 새로 이직한 회사에서 소스 분석은 해야겠는데 방대한 크기에 전체 파일과 디렉토리를 다운 받을 엄두가 안 난다면 아래 방법대로 검색하여 원하는 파일과 디렉토리를 통채로 받아올 수 있다.

먼저 파일질라를 실행 후 FPT에 접속한채로 상단 메뉴에서 서버(S)를 선택한다. 단축키는 F3

우측 상단 탐색기에서 최상위 폴더에서 검색을 하고 싶다면 최상위 폴더를 선택, 특정 폴더의 하위에서 검색을 하고 싶다면 해당 폴더를 선택한다.

난 adminarea를 기준으로 검색을 하기 위해 루트가 아닌 adminarea를 선택했다.
검색유형, 검색디렉터리, 검색조건 아래에 보면 파일명 또는 크기, 날짜 등 검색 필터를 선택하는 메뉴가 보인다.
여기에서 파일명과 다음으로 종료 콤보박스를 선택한 후 원하는 파일확장자를 .과 함께 입력해준다.
난 asp만 다운받을 예정이므로 .asp 를 입력하였다.

그리고 검색을 누르면 아래와 같이 현 상태의 디렉터리를 기준으로 그 하위 디렉터리에서 모든 ASP파일을 검색해 낸다.

이제 결과에서 ctrl + a를 눌러 모든 파일을 선택한 후 마우스 오른쪽 버튼을 눌러 팝업윈도우가 나오면 다운로드를 선택한다.

다운로드가 되길 원하는 위치를 선택하고 확인을 누르면 원하는대로 asp확장자의 파일만 다운받을 수 있다.

이것 말고도 ctrl + I를 눌러 디렉터리 목록 조회 필터 기능이 있다는데 잘 안되길래 그냥 포기하고 이 방법으로 진행했다.

반응형
Posted by Hippalus
,

반응형

sleep 함수가 여러개 존재하지만 잘 동작 안하는 소스들이 있는데 아래 소스는 잘 동작함

    <% 
        function Sleep(seconds)
            set oShell = CreateObject("Wscript.Shell")
            cmd = "%COMSPEC% /c timeout " & seconds & " /nobreak"
            oShell.Run cmd,0,1
        End function

        Sleep(5)

        response.write("End") 
    %>

https://stackoverflow.com/questions/2237393/how-to-delay-a-response-in-classic-asp

반응형
Posted by Hippalus
,

반응형

1차원 배열은 redim Preserve로 가능하지만
2차원 배열은 redim Preserve 순간 오류를 발생시킨다.
따라서 2차원 배열의 동적 할당을 원할 경우 최대 행 개수로 미리 Row를 할당시키는 수 밖에 없다.
사실상 절반의 동적 할당만 가능하다.

무슨 소리냐면
로직을 진행시키며 for문 등에서 조건에 맞을 때만 2차원 배열을 증가시키고 싶을 때가 있는데 이때 불가능하다란 이야기이다.
좀더 구체적으로 보자면
db에서 select를 해온다 치자
레코드의 수가 100건이다면 2차원 배열을 아래처럼 100개의 row를 보유한 2차원 배열 생성이 가능하다.
ReDim arrData(레코드의카운트-1, 1)
그런데 100건 중 특정 값을 갖고 있는 배열로만 생성하고 싶다하여 아래처럼 불가능하다.
nCount = 0
do until rs.eof
   if rs("isData") = "Y" then
      ReDim Preserve arrSlideImg(nCount , 1)
      nCount = nCount +1
   end if
   rs.movenext
loop

따라서 굳이 동적 할당이 필요하다면 일단 레코드의 수만큼만 배열을 생성하고
배열을 돌며 실제 출력할 때 빈 배열이면 exit for등으로 탈출하는 수 밖에 없다.

아래는 일반적인 2차원 배열의 동적 할당 코드 샘플이다.

<%
Dim arrData() ' 2차원 배열 선언
Dim numRows ' 행(row)의 개수를 저장할 변수

' 행(row)의 개수를 가변적으로 지정
Dim maxRows ' 최대 행(row) 개수
maxRows = 10 ' 예제에서는 최대 10으로 지정

' 변수의 값을 조건에 따라 증가시키며 배열 크기 동적 할당
numRows = 0 ' 초기 행(row) 개수는 0
ReDim arrData(maxRows - 1, 1) ' 배열 크기 동적 할당
Do While numRows < maxRows
    numRows = numRows + 1 ' 행(row) 개수 증가

    ' 배열에 데이터 채우기
    arrData(numRows - 1, 0) = numRows ' 첫 번째 열(column)에는 행(row) 번호 저장
    arrData(numRows - 1, 1) = "Data " & numRows ' 두 번째 열(column)에는 데이터 저장
Loop

' 배열 데이터 출력
Response.Write("<table border='1'>")
For i = 0 To numRows - 1
    Response.Write("<tr>")
    For j = 0 To 1
        Response.Write("<td>" & arrData(i, j) & "</td>")
    Next
    Response.Write("</tr>")
Next
Response.Write("</table>")
%>

반응형
Posted by Hippalus
,

반응형

 -- MSSQL 전체컬럼 확인방법
SELECT
   TBLNAME.name AS TBLNAME, COLNAME.name AS COLNAME
FROM
   sys.tables AS TBLNAME
   INNER JOIN sys.columns AS COLNAME ON TBLNAME.object_id = COLNAME.object_id


-- MSSQL 특정컬럼 검색방법
SELECT
   TBLNAME.name AS table_name, COLNAME.name AS column_name
FROM
   sys.tables AS TBLNAME
   INNER JOIN sys.columns AS COLNAME ON TBLNAME.object_id = COLNAME.object_id
WHERE
COLNAME.name = '찾으려는 컬럼명'

반응형
Posted by Hippalus
,

반응형

보통 게시판 페이징 쿼리를 만들 때 두가지 방법을 쓴다.
구닥다리 방법은 먼저 불러올 전체 카운트를 구하고 이를 토대로 실제 불러오는 쿼리에서 NOT IN으로 제외하고 불러오는 쿼리인데
똑같은 쿼리를 남발해야 하므로 아직도 사용하는 곳이 있다면 문제가 심각해 보이므로 PASS

두번째 방법은 ROW_NUMBER를 이용하는 쿼리인데 ROW_NUMBER()로 내마음속 번호를 생성시킨 후 이를 기준으로 페이징을 한다.
그나마 써줄만하다.

SELECT
   MEMTBL.USERID_IDX
FROM (
   SELECT ROW_NUMBER() OVER (ORDER BY USERID_IDX) AS ROWNUM, USERID_IDX FROM MEMBER_TABLE 
       ) AS MEMTBL
WHERE
   MEMTBL.ROWNUM BETWEEN 1 AND 10
 
마지막으로 MS-SQL 2012 이후 부터 사용가능한 쿼리인데 아래처럼 간결한 쿼리가 가능해졌다.

SELECT
   USERID_IDX
FROM
   MEMBER_TABLE WITH (NOLOCK)
ORDER BY 
   USERID_IDX
OFFSET 0 ROWS FETCH NEXT 10 ROWS ONLY

시작위치는 OFFSET으로 지정하고
FETCH NEXT로 몇번까지 불러올지 지정만 하면 그만이다.

반응형
Posted by Hippalus
,

반응형

애플 소셜 로그인을 구현하다 보면 p8 파일 때문에 고생을 하지만 이 부분만 구현되면 다른건 문제가 되지 않는다.
딱 하나 애플은 이메일을 공개하거나 사이트마다 새로운 이메일을 생성하여 해당 사이트에 제공하도록 privaterelay.appleid.com 서비스를 제공한다.
privaterelay.appleid.com로 매핑하여 원본 이메일에 메일을 발송한다란건데
애플 소셜 로그인 구현 후 이런 이메일에 그냥 메일을 발송하면 100% 발송 실패가 뜬다.

이를 해결하기 위해 아래처럼 애플 사이트에서 사전 설정 작업을 진행해야 한다.

 

개발자 사이트 접속
https://developer.apple.com/kr/

계정(account) 메뉴 선택
https://developer.apple.com/account

 


인증서, 식별자 및 프로파일 하단 메뉴들 중 아무메뉴나 선택 하면 좌측에 메뉴들 중 Services를 선택
Certificates
Identifiers
Devices
Profiles
Keys
Services



Sign in with Apple for Email Communication의 Configure버튼 선택하면 아래 링크로 최종 이동 된다.
https://developer.apple.com/account/resources/services/configure

여기에서 발송할 도메인과 Email을 입력하면 된다.
여러개인 경우 콤마(,)로 구분하면 됨

 

로그인 - Apple

 

idmsa.apple.com

 

반응형
Posted by Hippalus
,

반응형

척박한 국내 .net개발 환경 탓에 국내 기술 블로그를 통한 문제 해결이 쉽지 않다.
따라서 stackoverflow.com이나 구글링을 통해 문제를 해결해야 하는데 기본 셋팅인 한국어 오류로는 검색이 불가능하다.
따라서 영어 버전으로 visual studio 2022를 셋팅하여 사용해야 한다.

먼저 Visual Studio Installer를 실행한다.


수정을 누르면 아래와 같은 화면이 나타나는데 언어팩 탭메뉴를 선택 후 영어 체크박스를 체크해준다.

그리고 우측 하단의 수정버튼을 클릭하면 다운로드와 함께 언어패키지가 설치됨을 확인할 수 있다.

이제 Visual Studio 2022를 실행 후

도구 > 옵션 (단축키 alt + t, o) > 환경 > 국가별 설정에서 언어를 한국어에서 English로 바꿔주고 확인 버튼 클릭 후 수동으로 프로그램을 재시작 해주면 

드디어 영어버전을 확인할 수 있다.

Sorry King Sejong






반응형
Posted by Hippalus
,

반응형

Visual Studio Community 2022를 업그레이드 하다 실패로 인하여 재설치를 하게 되었는데 아래와 같이 설치 파일을 다운로드 하지 않았습니다. 라는 오류가 계속 떴다.

더 상황이 기괴한건 다운로드 속도다 잘 나와야 183KB
무슨 2400bps 모뎀도 아니고 2023년에 이기 머선 129 -_-

해결방법은 있다.
양형님들 사이트에서 hosts파일을 수정하여 IP를 추가해주면 된다카더라.
https://stackoverflow.com/questions/72200029/not-able-to-install-visual-studio-2022-using-visual-studio-installer
스택오버플로우는 언제나 진실이다.



1. host파일이 있는 위치로 이동한다.
C:\Windows\System32\drivers\etc

2. hosts파일을 메모장(관리자권한으로 실행한)으로 불러들여 아이디 한칸 띄우고 download.visualstudio.microsoft.com 이렇게 입력하고 저장해주면 된다.
추가해줄 아이피 리스트는 아래에서 아무거나 골라서 추가하면 된다.
이렇게 말이다.
93.184.215.201 download.visualstudio.microsoft.com
68.232.34.200 download.visualstudio.microsoft.com
192.229.232.200 download.visualstudio.microsoft.com
36.25.247.107 download.visualstudio.microsoft.com
192.16.48.200 download.visualstudio.microsoft.com

그리고 다시 visual studio installer를 가보면 속도가 그나마 MB로 상향된것을 확인할 수 있을것이다.
만약 속도가 그대로라면 일시 중지 후 다시 이어서 시작하면 될 것이다.

이것 때문에 아무것도 못하고 반나절 이상 시간을 허비해버렸다.

 

 

반응형
Posted by Hippalus
,